diff --git a/Octokit.Tests.Integration/Clients/StatisticsClientTests.cs b/Octokit.Tests.Integration/Clients/StatisticsClientTests.cs index ce628868..a6b21bc5 100644 --- a/Octokit.Tests.Integration/Clients/StatisticsClientTests.cs +++ b/Octokit.Tests.Integration/Clients/StatisticsClientTests.cs @@ -1,5 +1,4 @@ using System.Linq; -using System.Net.Http.Headers; using System.Threading.Tasks; using Xunit; @@ -18,21 +17,31 @@ namespace Octokit.Tests.Integration.Clients } [IntegrationTest] - public async Task CanCreateAndRetrieveCommit() + public async Task CanCreateAndRetrieveContributors() { var repository = await CreateRepository(); await CommitToRepository(repository); var contributors = await _client.Repository.Statistics.GetContributors(repository.Owner, repository.Name); Assert.NotNull(contributors); - Assert.True(contributors.Count() == 1); + Assert.Equal(1, contributors.Count); var soleContributor = contributors.First(); Assert.NotNull(soleContributor.Author); Assert.True(soleContributor.Author.Login == repository.Owner); - Assert.True(soleContributor.Weeks.Count() == 1); - Assert.True(soleContributor.Total == 1); + Assert.Equal(1, soleContributor.Weeks.Count); + Assert.Equal(1, soleContributor.Total); + } + + [IntegrationTest] + public async Task CanCreateAndRetrieveEmptyContributors() + { + var repository = await CreateRepository(autoInit: false); + var contributors = await _client.Repository.Statistics.GetContributors(repository.Owner, repository.Name); + + Assert.NotNull(contributors); + Assert.Empty(contributors); } [IntegrationTest] @@ -42,10 +51,10 @@ namespace Octokit.Tests.Integration.Clients await CommitToRepository(repository); var commitActivities = await _client.Repository.Statistics.GetCommitActivity(repository.Owner, repository.Name); Assert.NotNull(commitActivities); - Assert.True(commitActivities.Activity.Count() == 52); + Assert.Equal(52, commitActivities.Activity.Count); var thisWeek = commitActivities.Activity.Last(); - Assert.True(thisWeek.Total == 1); + Assert.Equal(1, thisWeek.Total); Assert.NotNull(thisWeek.Days); } @@ -65,9 +74,7 @@ namespace Octokit.Tests.Integration.Clients var repository = await CreateRepository(); await CommitToRepository(repository); var weeklyCommitCounts = await _client.Repository.Statistics.GetParticipation(repository.Owner, repository.Name); - Assert.NotNull(weeklyCommitCounts); - Assert.NotNull(weeklyCommitCounts.All); - Assert.NotNull(weeklyCommitCounts.Owner); + Assert.Equal(52, weeklyCommitCounts.All.Count); } [IntegrationTest] @@ -80,10 +87,10 @@ namespace Octokit.Tests.Integration.Clients Assert.NotNull(punchCard.PunchPoints); } - async Task CreateRepository() + async Task CreateRepository(bool autoInit = true) { var repoName = Helper.MakeNameWithTimestamp("public-repo"); - var repository = await _client.Repository.Create(new NewRepository(repoName) { AutoInit = true }); + var repository = await _client.Repository.Create(new NewRepository(repoName) { AutoInit = autoInit }); return new RepositorySummary { Owner = repository.Owner.Login, diff --git a/Octokit.Tests/Clients/StatisticsClientTests.cs b/Octokit.Tests/Clients/StatisticsClientTests.cs index 9a1aba76..102647a0 100644 --- a/Octokit.Tests/Clients/StatisticsClientTests.cs +++ b/Octokit.Tests/Clients/StatisticsClientTests.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Threading.Tasks; using NSubstitute; -using Octokit.Tests.Helpers; using Xunit; namespace Octokit.Tests.Clients @@ -21,16 +21,33 @@ namespace Octokit.Tests.Clients public class TheGetContributorsMethod { [Fact] - public void RequestsCorrectUrl() + public async Task RetrievesContributorsForCorrectUrl() { var expectedEndPoint = new Uri("/repos/username/repositoryName/stats/contributors", UriKind.Relative); - var client = Substitute.For(); + IReadOnlyList contributors = new ReadOnlyCollection(new[] { new Contributor() }); + client.GetQueuedOperation>(expectedEndPoint, Args.CancellationToken) + .Returns(Task.FromResult(contributors)); var statisticsClient = new StatisticsClient(client); - statisticsClient.GetContributors("username","repositoryName"); + var result = await statisticsClient.GetContributors("username","repositoryName"); - client.Received().GetQueuedOperation>(expectedEndPoint,Args.CancellationToken); + Assert.Equal(1, result.Count); + } + + [Fact] + public async Task RetrievesEmptyContributorsCollectionWhenNoContentReturned() + { + var expectedEndPoint = new Uri("/repos/username/repositoryName/stats/contributors", UriKind.Relative); + var client = Substitute.For(); + IReadOnlyList contributors = null; + client.GetQueuedOperation>(expectedEndPoint, Args.CancellationToken) + .Returns(Task.FromResult(contributors)); + var statisticsClient = new StatisticsClient(client); + + var result = await statisticsClient.GetContributors("username", "repositoryName"); + + Assert.Empty(result); } [Fact] diff --git a/Octokit.Tests/Http/ApiConnectionTests.cs b/Octokit.Tests/Http/ApiConnectionTests.cs index 909c2b10..11d1aa09 100644 --- a/Octokit.Tests/Http/ApiConnectionTests.cs +++ b/Octokit.Tests/Http/ApiConnectionTests.cs @@ -361,6 +361,22 @@ namespace Octokit.Tests.Http Assert.Same(actualResult,result); } + [Fact] + public async Task WhenGetReturnsNoContentThenReturnsNull() + { + var queuedOperationUrl = new Uri("anything", UriKind.Relative); + + var result = new object(); + const HttpStatusCode statusCode = HttpStatusCode.NoContent; + IApiResponse response = new ApiResponse(new Response(statusCode, null, new Dictionary(), "application/json"), result); + var connection = Substitute.For(); + connection.GetResponse(queuedOperationUrl, Args.CancellationToken).Returns(Task.FromResult(response)); + var apiConnection = new ApiConnection(connection); + + var actualResult = await apiConnection.GetQueuedOperation(queuedOperationUrl, Args.CancellationToken); + Assert.Null(actualResult); + } + [Fact] public async Task GetIsRepeatedUntilHttpStatusCodeOkIsReturned() { diff --git a/Octokit/Clients/IStatisticsClient.cs b/Octokit/Clients/IStatisticsClient.cs index 1ea3fad9..ff97aca9 100644 --- a/Octokit/Clients/IStatisticsClient.cs +++ b/Octokit/Clients/IStatisticsClient.cs @@ -18,7 +18,7 @@ namespace Octokit /// The owner of the repository /// The name of the repository /// A list of - Task> GetContributors(string owner, string repositoryName); + Task> GetContributors(string owner, string repositoryName); /// /// Returns a list of for the given repository @@ -27,7 +27,7 @@ namespace Octokit /// The name of the repository /// A token used to cancel this potentially long running request /// A list of - Task> GetContributors(string owner, string repositoryName, CancellationToken cancellationToken); + Task> GetContributors(string owner, string repositoryName, CancellationToken cancellationToken); /// /// Returns the last year of commit activity grouped by week. diff --git a/Octokit/Clients/StatisticsClient.cs b/Octokit/Clients/StatisticsClient.cs index 5ac2cd80..5cd132bf 100644 --- a/Octokit/Clients/StatisticsClient.cs +++ b/Octokit/Clients/StatisticsClient.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -26,7 +28,7 @@ namespace Octokit /// The owner of the repository /// The name of the repository /// A list of - public Task> GetContributors(string owner, string repositoryName) + public Task> GetContributors(string owner, string repositoryName) { return GetContributors(owner, repositoryName, CancellationToken.None); } @@ -38,13 +40,14 @@ namespace Octokit /// The name of the repository /// A token used to cancel this potentially long running request /// A list of - public async Task> GetContributors(string owner, string repositoryName, CancellationToken cancellationToken) + public async Task> GetContributors(string owner, string repositoryName, CancellationToken cancellationToken) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(repositoryName, "repositoryName"); var endpoint = "/repos/{0}/{1}/stats/contributors".FormatUri(owner, repositoryName); - return await ApiConnection.GetQueuedOperation>(endpoint, cancellationToken); + return await ApiConnection.GetQueuedOperation>(endpoint, cancellationToken) + ?? new ReadOnlyCollection(new Contributor[] {}); } /// diff --git a/Octokit/Http/ApiConnection.cs b/Octokit/Http/ApiConnection.cs index 18991d3a..64d312d1 100644 --- a/Octokit/Http/ApiConnection.cs +++ b/Octokit/Http/ApiConnection.cs @@ -444,6 +444,8 @@ namespace Octokit { case HttpStatusCode.Accepted: continue; + case HttpStatusCode.NoContent: + return default(T); case HttpStatusCode.OK: return response.Body; } diff --git a/Octokit/Http/IApiConnection.cs b/Octokit/Http/IApiConnection.cs index 8a7c36bd..0c06b130 100644 --- a/Octokit/Http/IApiConnection.cs +++ b/Octokit/Http/IApiConnection.cs @@ -262,6 +262,6 @@ namespace Octokit /// A token used to cancel this potentially long running request /// The updated API resource. /// Thrown when an API error occurs. - Task GetQueuedOperation(Uri uri,CancellationToken cancellationToken); + Task GetQueuedOperation(Uri uri, CancellationToken cancellationToken); } -} \ No newline at end of file +}