WIP checkin for getting last ApiInfo object

This commit is contained in:
Mark Taylor
2015-07-31 10:35:51 +01:00
parent a7bc09e767
commit f8ee4f94a1
19 changed files with 241 additions and 7 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
namespace Octokit.Reactive
{
public interface IObservableGitHubClient
public interface IObservableGitHubClient : IApiInfo
{
IConnection Connection { get; }
@@ -68,5 +68,11 @@ namespace Octokit.Reactive
public IObservableNotificationsClient Notification { get; private set; }
public IObservableGitDatabaseClient GitDatabase { get; private set; }
public IObservableSearchClient Search { get; private set; }
/// <summary>
/// Gets the latest API Info - this will be null if no API calls have been made
/// </summary>
/// <returns><seealso cref="ApiInfo"/> representing the information returned as part of an Api call</returns>
public ApiInfo LastApiInfo { get { return _gitHubClient.Connection.LastApiInfo; } }
}
}
@@ -0,0 +1,32 @@
using Octokit.Tests.Integration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
public class GitHubClientTests
{
public class TheLastApiInfoProperty
{
[IntegrationTest]
public async Task CanRetrieveLastApiInfo()
{
var github = Helper.GetAuthenticatedClient();
// Doesn't matter which API gets called
await github.Miscellaneous.GetRateLimits();
var result = github.LastApiInfo;
//Assert.True(result.Links.Count > 0);
//Assert.True(result.AcceptedOauthScopes.Count > 0);
//Assert.True(result.OauthScopes.Count > 0);
//Assert.False(String.IsNullOrEmpty(result.Etag));
Assert.True(result.RateLimit.Limit > 0);
Assert.True(result.RateLimit.Remaining > -1);
Assert.NotNull(result.RateLimit.Reset);
}
}
}
@@ -75,6 +75,7 @@
<Compile Include="Clients\AuthorizationClientTests.cs" />
<Compile Include="Clients\BlobClientTests.cs" />
<Compile Include="Clients\BranchesClientTests.cs" />
<Compile Include="Clients\GitHubClientTests.cs" />
<Compile Include="Clients\MergingClientTests.cs" />
<Compile Include="Clients\CommitsClientTests.cs" />
<Compile Include="Clients\CommitStatusClientTests.cs" />
+67
View File
@@ -5,6 +5,7 @@ using NSubstitute;
using Octokit.Internal;
using Xunit;
using Xunit.Extensions;
using System.Collections.Generic;
namespace Octokit.Tests
{
@@ -104,5 +105,71 @@ namespace Octokit.Tests
Assert.Equal("bar", client.Credentials.Password);
}
}
public class TheLastApiInfoProperty
{
[Fact]
public async Task ReturnsNullIfNew()
{
var connection = Substitute.For<IConnection>();
connection.LastApiInfo.Returns((ApiInfo)null);
var client = new GitHubClient(connection);
var result = client.LastApiInfo;
Assert.Null(result);
var temp = connection.Received(1).LastApiInfo;
}
[Fact]
public async Task ReturnsObjectIfNotNew()
{
var apiInfo = new ApiInfo(
new Dictionary<string, Uri>
{
{
"next",
new Uri("https://api.github.com/repos/rails/rails/issues?page=4&per_page=5")
},
{
"last",
new Uri("https://api.github.com/repos/rails/rails/issues?page=131&per_page=5")
},
{
"first",
new Uri("https://api.github.com/repos/rails/rails/issues?page=1&per_page=5")
},
{
"prev",
new Uri("https://api.github.com/repos/rails/rails/issues?page=2&per_page=5")
}
},
new List<string>
{
"user",
},
new List<string>
{
"user",
"public_repo",
"repo",
"gist"
},
"5634b0b187fd2e91e3126a75006cc4fa",
new RateLimit(100, 75, 1372700873)
);
var connection = Substitute.For<IConnection>();
connection.LastApiInfo.Returns(apiInfo);
var client = new GitHubClient(connection);
var result = client.LastApiInfo;
Assert.NotNull(result);
var temp = connection.Received(1).LastApiInfo;
}
}
}
}
+80
View File
@@ -564,5 +564,85 @@ namespace Octokit.Tests.Http
Assert.True(connection.UserAgent.StartsWith("OctokitTests ("));
}
}
public class TheLastAPiInfoProperty
{
[Fact]
public async Task ReturnsNullIfNew()
{
var httpClient = Substitute.For<IHttpClient>();
httpClient.LastApiInfo.Returns((ApiInfo)null);
var connection = new Connection(new ProductHeaderValue("OctokitTests"),
_exampleUri,
Substitute.For<ICredentialStore>(),
httpClient,
Substitute.For<IJsonSerializer>());
var result = connection.LastApiInfo;
Assert.Null(result);
var temp = httpClient.Received(1).LastApiInfo;
}
[Fact]
public async Task ReturnsObjectIfNotNew()
{
var apiInfo = new ApiInfo(
new Dictionary<string, Uri>
{
{
"next",
new Uri("https://api.github.com/repos/rails/rails/issues?page=4&per_page=5")
},
{
"last",
new Uri("https://api.github.com/repos/rails/rails/issues?page=131&per_page=5")
},
{
"first",
new Uri("https://api.github.com/repos/rails/rails/issues?page=1&per_page=5")
},
{
"prev",
new Uri("https://api.github.com/repos/rails/rails/issues?page=2&per_page=5")
}
},
new List<string>
{
"user",
},
new List<string>
{
"user",
"public_repo",
"repo",
"gist"
},
"5634b0b187fd2e91e3126a75006cc4fa",
new RateLimit(100, 75, 1372700873)
);
var httpClient = Substitute.For<IHttpClient>();
httpClient.LastApiInfo.Returns(apiInfo);
var connection = new Connection(new ProductHeaderValue("OctokitTests"),
_exampleUri,
Substitute.For<ICredentialStore>(),
httpClient,
Substitute.For<IJsonSerializer>());
var result = connection.LastApiInfo;
// No point checking all of the values as they are tested elsewhere
// Just provde that the ApiInfo is populated
Assert.Equal(4, result.Links.Count);
Assert.Equal(1, result.OauthScopes.Count);
Assert.Equal(4, result.AcceptedOauthScopes.Count);
Assert.Equal("5634b0b187fd2e91e3126a75006cc4fa", result.Etag);
Assert.Equal(100, result.RateLimit.Limit);
var temp = httpClient.Received(1).LastApiInfo;
}
}
}
}
+6
View File
@@ -100,6 +100,12 @@ namespace Octokit
Deployment = new DeploymentsClient(apiConnection);
}
/// <summary>
/// Gets the latest API Info - this will be null if no API calls have been made
/// </summary>
/// <returns><seealso cref="ApiInfo"/> representing the information returned as part of an Api call</returns>
public ApiInfo LastApiInfo { get { return Connection.LastApiInfo; } }
/// <summary>
/// Convenience property for getting and setting credentials.
/// </summary>
+6
View File
@@ -136,6 +136,12 @@ namespace Octokit
_jsonPipeline = new JsonHttpPipeline();
}
/// <summary>
/// Gets the latest API Info - this will be null if no API calls have been made
/// </summary>
/// <returns><seealso cref="ApiInfo"/> representing the information returned as part of an Api call</returns>
public ApiInfo LastApiInfo { get { return _httpClient.LastApiInfo; } }
public Task<IApiResponse<T>> Get<T>(Uri uri, IDictionary<string, string> parameters, string accepts)
{
Ensure.ArgumentNotNull(uri, "uri");
+11 -1
View File
@@ -28,6 +28,12 @@ namespace Octokit.Internal
_http = new HttpClient(new RedirectHandler { InnerHandler = getHandler() });
}
/// <summary>
/// Gets the latest API Info - this will be null if no API calls have been made
/// </summary>
/// <returns><seealso cref="ApiInfo"/> representing the information returned as part of an Api call</returns>
public ApiInfo LastApiInfo { get; private set; }
/// <summary>
/// Sends the specified request and returns a response.
/// </summary>
@@ -45,7 +51,11 @@ namespace Octokit.Internal
// Make the request
var responseMessage = await _http.SendAsync(requestMessage, HttpCompletionOption.ResponseContentRead, cancellationTokenForRequest)
.ConfigureAwait(false);
return await BuildResponse(responseMessage).ConfigureAwait(false);
var response = await BuildResponse(responseMessage).ConfigureAwait(false);
LastApiInfo = response.ApiInfo;
return response;
}
}
+20
View File
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Octokit
{
/// <summary>
/// Provides a property for the Last recorded API infomation
/// </summary>
public interface IApiInfo
{
/// <summary>
/// Gets the latest API Info - this will be null if no API calls have been made
/// </summary>
/// <returns><seealso cref="ApiInfo"/> representing the information returned as part of an Api call</returns>
ApiInfo LastApiInfo { get; }
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ namespace Octokit
/// <summary>
/// A connection for making HTTP requests against URI endpoints.
/// </summary>
public interface IConnection
public interface IConnection : IApiInfo
{
/// <summary>
/// Performs an asynchronous HTTP GET request that expects a <seealso cref="IResponse"/> containing HTML.
+1 -1
View File
@@ -10,7 +10,7 @@ namespace Octokit.Internal
/// <remarks>
/// Most folks won't ever need to swap this out. But if you're trying to run this on Windows Phone, you might.
/// </remarks>
public interface IHttpClient : IDisposable
public interface IHttpClient : IDisposable, IApiInfo
{
/// <summary>
/// Sends the specified request and returns a response.
+1 -1
View File
@@ -5,7 +5,7 @@ namespace Octokit
/// <summary>
/// A Client for the GitHub API v3. You can read more about the api here: http://developer.github.com.
/// </summary>
public interface IGitHubClient
public interface IGitHubClient : IApiInfo
{
/// <summary>
/// Provides a client connection to make rest requests to HTTP endpoints.
+1
View File
@@ -399,6 +399,7 @@
<Compile Include="Models\Response\ResourceRateLimit.cs" />
<Compile Include="Models\Response\MiscellaneousRateLimit.cs" />
<Compile Include="Exceptions\RepositoryFormatException.cs" />
<Compile Include="Http\IApiInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
+2 -1
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -415,6 +415,7 @@
<Compile Include="Models\Response\ResourceRateLimit.cs" />
<Compile Include="Models\Response\MiscellaneousRateLimit.cs" />
<Compile Include="Exceptions\RepositoryFormatException.cs" />
<Compile Include="Http\IApiInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />
</Project>
+2 -1
View File
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -408,6 +408,7 @@
<Compile Include="Models\Response\ResourceRateLimit.cs" />
<Compile Include="Models\Response\MiscellaneousRateLimit.cs" />
<Compile Include="Exceptions\RepositoryFormatException.cs" />
<Compile Include="Http\IApiInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.MonoTouch.CSharp.targets" />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+1
View File
@@ -398,6 +398,7 @@
<Compile Include="Models\Response\ResourceRateLimit.cs" />
<Compile Include="Models\Response\MiscellaneousRateLimit.cs" />
<Compile Include="Exceptions\RepositoryFormatException.cs" />
<Compile Include="Http\IApiInfo.cs" />
</ItemGroup>
<ItemGroup>
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">
+1
View File
@@ -402,6 +402,7 @@
<Compile Include="Models\Response\ResourceRateLimit.cs" />
<Compile Include="Models\Response\MiscellaneousRateLimit.cs" />
<Compile Include="Exceptions\RepositoryFormatException.cs" />
<Compile Include="Http\IApiInfo.cs" />
</ItemGroup>
<ItemGroup>
<CodeAnalysisDictionary Include="..\CustomDictionary.xml">
+1
View File
@@ -84,6 +84,7 @@
<Compile Include="Helpers\PropertyOrField.cs" />
<Compile Include="Helpers\SerializeNullAttribute.cs" />
<Compile Include="Http\HttpMessageHandlerFactory.cs" />
<Compile Include="Http\IApiInfo.cs" />
<Compile Include="Http\ProductHeaderValue.cs" />
<Compile Include="Models\Request\GistFileUpdate.cs" />
<Compile Include="Models\Request\NewMerge.cs" />