[WIP] Add repository traffic preview (#1457)

* Add response models

* Supress message

* correct spelling Timestamp

* implement traffic client

* add reactive client

* [WIP] unit tests

* add argument check

* finish unit tests

* add integration tests

* Change repositoryId from int to long
Remove GetAll naming of endpoints and add to PaginationTest exclusions
Rename View and Clone classes to be more specific
Add handling of TimeStamp fields being UtcUnix time
Add integration tests for repositoryId methods
This commit is contained in:
Martin Scholz
2016-09-28 17:16:58 +02:00
committed by Ryan Gribble
parent 693cc29dd5
commit a57fb1278d
31 changed files with 1281 additions and 2 deletions

View File

@@ -592,5 +592,13 @@ namespace Octokit.Reactive
/// See the <a href="https://developer.github.com/v3/repos/invitations/">Repository Invitations API documentation</a> for more information. /// See the <a href="https://developer.github.com/v3/repos/invitations/">Repository Invitations API documentation</a> for more information.
/// </remarks> /// </remarks>
IObservableRepositoryInvitationsClient Invitation { get; } IObservableRepositoryInvitationsClient Invitation { get; }
/// <summary>
/// Access GitHub's Repository Traffic API
/// </summary>
/// <remarks>
/// Refer to the API documentation for more information: https://developer.github.com/v3/repos/traffic/
/// </remarks>
IObservableRepositoryTrafficClient Traffic { get; }
} }
} }

View File

@@ -0,0 +1,77 @@
using System;
namespace Octokit.Reactive
{
/// <summary>
/// A client for GitHub's Repository Traffic API.
/// </summary>
/// <remarks>
/// See the <a href="https://developer.github.com/v3/repos/traffic/">Repository Traffic API documentation</a> for more information.
/// </remarks>
public interface IObservableRepositoryTrafficClient
{
/// <summary>
/// List the top 10 referrers over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-referrers</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
IObservable<RepositoryTrafficReferrer> GetReferrers(string owner, string name);
/// <summary>
/// List the top 10 referrers over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-referrers</remarks>
/// <param name="repositoryId">The owner of the repository</param>
IObservable<RepositoryTrafficReferrer> GetReferrers(long repositoryId);
/// <summary>
/// List the top 10 popular contents over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-paths</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
IObservable<RepositoryTrafficPath> GetPaths(string owner, string name);
/// <summary>
/// List the top 10 popular contents over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-paths</remarks>
/// <param name="repositoryId">The owner of the repository</param>
IObservable<RepositoryTrafficPath> GetPaths(long repositoryId);
/// <summary>
/// Get the total number of views and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#views</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="per">Breakdown per day or week</param>
IObservable<RepositoryTrafficViewSummary> GetViews(string owner, string name, RepositoryTrafficRequest per);
/// <summary>
/// Get the total number of views and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#views</remarks>
/// <param name="repositoryId">The owner of the repository</param>
/// <param name="per">Breakdown per day or week</param>
IObservable<RepositoryTrafficViewSummary> GetViews(long repositoryId, RepositoryTrafficRequest per);
/// <summary>
/// Get the total number of clones and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#clones</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="per">Breakdown per day or week</param>
IObservable<RepositoryTrafficCloneSummary> GetClones(string owner, string name, RepositoryTrafficRequest per);
/// <summary>
/// Get the total number of clones and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#clones</remarks>
/// <param name="repositoryId">The owner of the repository</param>
/// <param name="per">Breakdown per day or week</param>
IObservable<RepositoryTrafficCloneSummary> GetClones(long repositoryId, RepositoryTrafficRequest per);
}
}

View File

@@ -38,7 +38,7 @@ namespace Octokit.Reactive
Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNullOrEmptyString(name, "name");
return GetAll(owner, name, ApiOptions.None); return GetAll(owner, name, ApiOptions.None);
} }
/// <summary> /// <summary>

View File

@@ -36,6 +36,7 @@ namespace Octokit.Reactive
Merging = new ObservableMergingClient(client); Merging = new ObservableMergingClient(client);
Page = new ObservableRepositoryPagesClient(client); Page = new ObservableRepositoryPagesClient(client);
Invitation = new ObservableRepositoryInvitationsClient(client); Invitation = new ObservableRepositoryInvitationsClient(client);
Traffic = new ObservableRepositoryTrafficClient(client);
} }
/// <summary> /// <summary>
@@ -880,6 +881,14 @@ namespace Octokit.Reactive
/// <remarks> /// <remarks>
/// See the <a href="https://developer.github.com/v3/repos/invitations/">Repository Invitations API documentation</a> for more information. /// See the <a href="https://developer.github.com/v3/repos/invitations/">Repository Invitations API documentation</a> for more information.
/// </remarks> /// </remarks>
public IObservableRepositoryInvitationsClient Invitation { get; private set; } public IObservableRepositoryInvitationsClient Invitation { get; private set; }
/// <summary>
/// Access GitHub's Repository Traffic API
/// </summary>
/// <remarks>
/// Refer to the API documentation for more information: https://developer.github.com/v3/repos/traffic/
/// </remarks>
public IObservableRepositoryTrafficClient Traffic { get; private set; }
} }
} }

View File

@@ -0,0 +1,124 @@
using System;
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;
namespace Octokit.Reactive
{
public class ObservableRepositoryTrafficClient : IObservableRepositoryTrafficClient
{
readonly IRepositoryTrafficClient _client;
public ObservableRepositoryTrafficClient(IGitHubClient client)
{
Ensure.ArgumentNotNull(client, "client");
_client = client.Repository.Traffic;
}
/// <summary>
/// List the top 10 popular contents over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-paths</remarks>
/// <param name="repositoryId">The owner of the repository</param>
public IObservable<RepositoryTrafficPath> GetPaths(long repositoryId)
{
return _client.GetPaths(repositoryId).ToObservable().SelectMany(x => x);
}
/// <summary>
/// List the top 10 popular contents over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-paths</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
public IObservable<RepositoryTrafficPath> GetPaths(string owner, string name)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
return _client.GetPaths(owner, name).ToObservable().SelectMany(x => x);
}
/// <summary>
/// List the top 10 referrers over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-referrers</remarks>
/// <param name="repositoryId">The owner of the repository</param>
public IObservable<RepositoryTrafficReferrer> GetReferrers(long repositoryId)
{
return _client.GetReferrers(repositoryId).ToObservable().SelectMany(x => x);
}
/// <summary>
/// List the top 10 referrers over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-referrers</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
public IObservable<RepositoryTrafficReferrer> GetReferrers(string owner, string name)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
return _client.GetReferrers(owner, name).ToObservable().SelectMany(x => x);
}
/// <summary>
/// Get the total number of clones and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#clones</remarks>
/// <param name="repositoryId">The owner of the repository</param>
/// <param name="per">Breakdown per day or week</param>
public IObservable<RepositoryTrafficCloneSummary> GetClones(long repositoryId, RepositoryTrafficRequest per)
{
Ensure.ArgumentNotNull(per, "per");
return _client.GetClones(repositoryId, per).ToObservable();
}
/// <summary>
/// Get the total number of clones and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#clones</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="per">Breakdown per day or week</param>
public IObservable<RepositoryTrafficCloneSummary> GetClones(string owner, string name, RepositoryTrafficRequest per)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNull(per, "per");
return _client.GetClones(owner, name, per).ToObservable();
}
/// <summary>
/// Get the total number of views and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#views</remarks>
/// <param name="repositoryId">The owner of the repository</param>
/// <param name="per">Breakdown per day or week</param>
public IObservable<RepositoryTrafficViewSummary> GetViews(long repositoryId, RepositoryTrafficRequest per)
{
Ensure.ArgumentNotNull(per, "per");
return _client.GetViews(repositoryId, per).ToObservable();
}
/// <summary>
/// Get the total number of views and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#views</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="per">Breakdown per day or week</param>
public IObservable<RepositoryTrafficViewSummary> GetViews(string owner, string name, RepositoryTrafficRequest per)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNull(per, "per");
return _client.GetViews(owner, name, per).ToObservable();
}
}
}

View File

@@ -196,6 +196,8 @@
<Compile Include="Clients\ObservableIssueTimelineClient.cs" /> <Compile Include="Clients\ObservableIssueTimelineClient.cs" />
<Compile Include="Clients\IObservableRepositoryBranchesClient.cs" /> <Compile Include="Clients\IObservableRepositoryBranchesClient.cs" />
<Compile Include="Clients\ObservableRepositoryBranchesClient.cs" /> <Compile Include="Clients\ObservableRepositoryBranchesClient.cs" />
<Compile Include="Clients\IObservableRepositoryTrafficClient.cs" />
<Compile Include="Clients\ObservableRepositoryTrafficClient.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup> <ItemGroup>

View File

@@ -212,6 +212,8 @@
<Compile Include="Clients\ObservableIssueTimelineClient.cs" /> <Compile Include="Clients\ObservableIssueTimelineClient.cs" />
<Compile Include="Clients\IObservableRepositoryBranchesClient.cs" /> <Compile Include="Clients\IObservableRepositoryBranchesClient.cs" />
<Compile Include="Clients\ObservableRepositoryBranchesClient.cs" /> <Compile Include="Clients\ObservableRepositoryBranchesClient.cs" />
<Compile Include="Clients\IObservableRepositoryTrafficClient.cs" />
<Compile Include="Clients\ObservableRepositoryTrafficClient.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />
<ItemGroup> <ItemGroup>

View File

@@ -208,6 +208,8 @@
<Compile Include="Clients\ObservableIssueTimelineClient.cs" /> <Compile Include="Clients\ObservableIssueTimelineClient.cs" />
<Compile Include="Clients\IObservableRepositoryBranchesClient.cs" /> <Compile Include="Clients\IObservableRepositoryBranchesClient.cs" />
<Compile Include="Clients\ObservableRepositoryBranchesClient.cs" /> <Compile Include="Clients\ObservableRepositoryBranchesClient.cs" />
<Compile Include="Clients\IObservableRepositoryTrafficClient.cs" />
<Compile Include="Clients\ObservableRepositoryTrafficClient.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup> <ItemGroup>

View File

@@ -99,6 +99,7 @@
<Compile Include="Clients\IObservableMigrationClient.cs" /> <Compile Include="Clients\IObservableMigrationClient.cs" />
<Compile Include="Clients\IObservableOauthClient.cs" /> <Compile Include="Clients\IObservableOauthClient.cs" />
<Compile Include="Clients\IObservablePullRequestReviewCommentReactionsClient.cs" /> <Compile Include="Clients\IObservablePullRequestReviewCommentReactionsClient.cs" />
<Compile Include="Clients\IObservableRepositoryTrafficClient.cs" />
<Compile Include="Clients\ObservableRepositoryBranchesClient.cs" /> <Compile Include="Clients\ObservableRepositoryBranchesClient.cs" />
<Compile Include="Clients\IObservableRepositoryBranchesClient.cs" /> <Compile Include="Clients\IObservableRepositoryBranchesClient.cs" />
<Compile Include="Clients\IObservableRepositoryCommitsClients.cs" /> <Compile Include="Clients\IObservableRepositoryCommitsClients.cs" />
@@ -141,6 +142,7 @@
<Compile Include="Clients\ObservableRepositoryContentsClient.cs" /> <Compile Include="Clients\ObservableRepositoryContentsClient.cs" />
<Compile Include="Clients\ObservableRepositoryInvitationsClient.cs" /> <Compile Include="Clients\ObservableRepositoryInvitationsClient.cs" />
<Compile Include="Clients\ObservableRepositoryPagesClient.cs" /> <Compile Include="Clients\ObservableRepositoryPagesClient.cs" />
<Compile Include="Clients\ObservableRepositoryTrafficClient.cs" />
<Compile Include="Clients\ObservableSearchClient.cs" /> <Compile Include="Clients\ObservableSearchClient.cs" />
<Compile Include="Clients\IObservableBlobsClient.cs" /> <Compile Include="Clients\IObservableBlobsClient.cs" />
<Compile Include="Clients\IObservableGistCommentsClient.cs" /> <Compile Include="Clients\IObservableGistCommentsClient.cs" />

View File

@@ -0,0 +1,111 @@
using Octokit;
using Octokit.Tests.Integration;
using System.Threading.Tasks;
using Xunit;
public class RepositoryTrafficClientTests
{
readonly IRepositoryTrafficClient _fixture;
readonly IGitHubClient _github;
readonly string _owner;
readonly string _repo;
readonly long _repoId;
public RepositoryTrafficClientTests()
{
_github = Helper.GetAuthenticatedClient();
_fixture = _github.Repository.Traffic;
_owner = "octokit";
_repo = "octokit.net";
_repoId = _github.Repository.Get(_owner, _repo).Result.Id;
}
public class TheGetReferrersMethod : RepositoryTrafficClientTests
{
[IntegrationTest]
public async Task GetsReferrers()
{
var referrers = await _fixture.GetReferrers(_owner, _repo);
Assert.True(referrers.Count > 0);
}
[IntegrationTest]
public async Task GetsReferrersWithRepositoryId()
{
var referrers = await _fixture.GetReferrers(_repoId);
Assert.True(referrers.Count > 0);
}
}
public class TheGetPathsMethod : RepositoryTrafficClientTests
{
[IntegrationTest]
public async Task GetsPaths()
{
var paths = await _fixture.GetPaths(_owner, _repo);
Assert.True(paths.Count > 0);
}
[IntegrationTest]
public async Task GetsPathsWithRepositoryId()
{
var paths = await _fixture.GetPaths(_repoId);
Assert.True(paths.Count > 0);
}
}
public class TheGetClonesMethod : RepositoryTrafficClientTests
{
[IntegrationTest]
public async Task GetsClones()
{
var request = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
var clones = await _fixture.GetClones(_owner, _repo, request);
Assert.True(clones.Count > 0);
Assert.True(clones.Clones.Count > 0);
Assert.True(clones.Uniques > 0);
}
[IntegrationTest]
public async Task GetsClonesWithRepositoryId()
{
var request = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
var clones = await _fixture.GetClones(_repoId, request);
Assert.True(clones.Count > 0);
Assert.True(clones.Clones.Count > 0);
Assert.True(clones.Uniques > 0);
}
}
public class TheGetViewsMethod : RepositoryTrafficClientTests
{
[IntegrationTest]
public async Task GetsViews()
{
var request = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
var views = await _fixture.GetViews(_owner, _repo, request);
Assert.True(views.Count > 0);
Assert.True(views.Views.Count > 0);
Assert.True(views.Uniques > 0);
}
[IntegrationTest]
public async Task GetsViewsWithRepositoryId()
{
var request = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
var views = await _fixture.GetViews(_repoId, request);
Assert.True(views.Count > 0);
Assert.True(views.Views.Count > 0);
Assert.True(views.Uniques > 0);
}
}
}

View File

@@ -112,6 +112,7 @@
<Compile Include="Clients\RepositoryHooksClientTests.cs" /> <Compile Include="Clients\RepositoryHooksClientTests.cs" />
<Compile Include="Clients\RepositoryInvitationsClientTests.cs" /> <Compile Include="Clients\RepositoryInvitationsClientTests.cs" />
<Compile Include="Clients\RepositoryPagesClientTests.cs" /> <Compile Include="Clients\RepositoryPagesClientTests.cs" />
<Compile Include="Clients\RepositoryTrafficClientTests.cs" />
<Compile Include="Clients\SearchClientTests.cs" /> <Compile Include="Clients\SearchClientTests.cs" />
<Compile Include="Clients\StarredClientTests.cs" /> <Compile Include="Clients\StarredClientTests.cs" />
<Compile Include="Clients\StatisticsClientTests.cs" /> <Compile Include="Clients\StatisticsClientTests.cs" />

View File

@@ -0,0 +1,181 @@
using NSubstitute;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit;
namespace Octokit.Tests.Clients
{
public class RepositoryTrafficClientTests
{
public class TheCtor
{
[Fact]
public void EnsuresNonNullArguments()
{
Assert.Throws<ArgumentNullException>(
() => new RepositoryTrafficClient(null));
}
}
public class TheGetAllReferrersMethod
{
[Fact]
public async Task RequestsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoryTrafficClient(connection);
await client.GetReferrers("fake", "repo");
connection.Received().GetAll<RepositoryTrafficReferrer>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/traffic/popular/referrers"), "application/vnd.github.spiderman-preview");
}
[Fact]
public async Task RequestsCorrectUrlWithRepositoryId()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoryTrafficClient(connection);
await client.GetReferrers(1);
connection.Received().GetAll<RepositoryTrafficReferrer>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/traffic/popular/referrers"), "application/vnd.github.spiderman-preview");
}
[Fact]
public async Task EnsuresNonNullArguments()
{
var client = new RepositoryTrafficClient(Substitute.For<IApiConnection>());
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetReferrers(null, "name"));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetReferrers("owner", null));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetReferrers("", "name"));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetReferrers("owner", ""));
}
}
public class TheGetAllPathsMethod
{
[Fact]
public async Task RequestsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoryTrafficClient(connection);
await client.GetPaths("fake", "repo");
connection.Received().GetAll<RepositoryTrafficPath>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/traffic/popular/paths"), "application/vnd.github.spiderman-preview");
}
[Fact]
public async Task RequestsCorrectUrlWithRepositoryId()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoryTrafficClient(connection);
await client.GetPaths(1);
connection.Received().GetAll<RepositoryTrafficPath>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/traffic/popular/paths"), "application/vnd.github.spiderman-preview");
}
[Fact]
public async Task EnsuresNonNullArguments()
{
var client = new RepositoryTrafficClient(Substitute.For<IApiConnection>());
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetPaths(null, "name"));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetPaths("owner", null));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetPaths("", "name"));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetPaths("owner", ""));
}
}
public class TheGetClonesMethod
{
[Fact]
public async Task RequestsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoryTrafficClient(connection);
var per = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
await client.GetClones("fake", "repo", per);
connection.Received().Get<RepositoryTrafficCloneSummary>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/traffic/clones"), Arg.Is<Dictionary<string, string>>(s => s["per"] == "day"), "application/vnd.github.spiderman-preview");
}
[Fact]
public async Task RequestsCorrectUrlWithRepositoryId()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoryTrafficClient(connection);
var per = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
await client.GetClones(1, per);
connection.Received().Get<RepositoryTrafficCloneSummary>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/traffic/clones"), Arg.Is<Dictionary<string, string>>(s => s["per"] == "day"), "application/vnd.github.spiderman-preview");
}
[Fact]
public async Task EnsuresNonNullArguments()
{
var client = new RepositoryTrafficClient(Substitute.For<IApiConnection>());
var per = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetClones(null, "name", per));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetClones("owner", null, per));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetClones("owner", "name", null));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetClones("", "name", per));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetClones("owner", "", per));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetClones(1, null));
}
}
public class TheGetViewsMethod
{
[Fact]
public async Task RequestsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoryTrafficClient(connection);
var per = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
await client.GetViews("fake", "repo", per);
connection.Received().Get<RepositoryTrafficViewSummary>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/traffic/views"), Arg.Is<Dictionary<string, string>>(s => s["per"] == "day"), "application/vnd.github.spiderman-preview");
}
[Fact]
public async Task RequestsCorrectUrlWithRepositoryId()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoryTrafficClient(connection);
var per = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
await client.GetViews(1, per);
connection.Received().Get<RepositoryTrafficViewSummary>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/traffic/views"), Arg.Is<Dictionary<string, string>>(s => s["per"] == "day"), "application/vnd.github.spiderman-preview");
}
[Fact]
public async Task EnsuresNonNullArguments()
{
var client = new RepositoryTrafficClient(Substitute.For<IApiConnection>());
var per = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetViews(null, "name", per));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetViews("owner", null, per));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetViews("owner", "name", null));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetViews("", "name", per));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetViews("owner", "", per));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetViews(1, null));
}
}
}
}

View File

@@ -109,6 +109,7 @@
<Compile Include="Clients\RepositoryContentsClientTests.cs" /> <Compile Include="Clients\RepositoryContentsClientTests.cs" />
<Compile Include="Clients\RepositoryInvitationsClientTests.cs" /> <Compile Include="Clients\RepositoryInvitationsClientTests.cs" />
<Compile Include="Clients\RepositoryPagesClientTests.cs" /> <Compile Include="Clients\RepositoryPagesClientTests.cs" />
<Compile Include="Clients\RepositoryTrafficClientTests.cs" />
<Compile Include="Clients\RespositoryCommitsClientTests.cs" /> <Compile Include="Clients\RespositoryCommitsClientTests.cs" />
<Compile Include="Clients\SearchClientTests.cs" /> <Compile Include="Clients\SearchClientTests.cs" />
<Compile Include="Clients\GistCommentsClientTests.cs" /> <Compile Include="Clients\GistCommentsClientTests.cs" />
@@ -254,6 +255,7 @@
<Compile Include="Reactive\ObservableRepositoryDeployKeysClientTests.cs" /> <Compile Include="Reactive\ObservableRepositoryDeployKeysClientTests.cs" />
<Compile Include="Reactive\ObservableGistsTests.cs" /> <Compile Include="Reactive\ObservableGistsTests.cs" />
<Compile Include="Reactive\ObservableRepositoryHooksClientTests.cs" /> <Compile Include="Reactive\ObservableRepositoryHooksClientTests.cs" />
<Compile Include="Reactive\ObservableRepositoryTrafficClientTests.cs" />
<Compile Include="Reactive\ObservableRespositoryCommitsClientTests.cs" /> <Compile Include="Reactive\ObservableRespositoryCommitsClientTests.cs" />
<Compile Include="Reactive\ObservableStarredClientTests.cs" /> <Compile Include="Reactive\ObservableStarredClientTests.cs" />
<Compile Include="Reactive\ObservableStatisticsClientTests.cs" /> <Compile Include="Reactive\ObservableStatisticsClientTests.cs" />

View File

@@ -0,0 +1,179 @@
using NSubstitute;
using Octokit.Reactive;
using System;
using Xunit;
namespace Octokit.Tests.Reactive
{
public class ObservableRepositoryTrafficClientTests
{
public class TheCtor
{
[Fact]
public void EnsuresNonNullArguments()
{
Assert.Throws<ArgumentNullException>(() => new ObservableRepositoryTrafficClient(null));
}
}
public class TheGetAllReferrersMethod
{
[Fact]
public void RequestsCorrectUrl()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoryTrafficClient(gitHubClient);
client.GetReferrers("fake", "repo");
gitHubClient.Received().Repository.Traffic.GetReferrers("fake", "repo");
}
[Fact]
public void RequestsCorrectUrlWithRepositoryId()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoryTrafficClient(gitHubClient);
client.GetReferrers(1);
gitHubClient.Received().Repository.Traffic.GetReferrers(1);
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ObservableRepositoryTrafficClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => client.GetReferrers(null, "name"));
Assert.Throws<ArgumentNullException>(() => client.GetReferrers("owner", null));
Assert.Throws<ArgumentException>(() => client.GetReferrers("", "name"));
Assert.Throws<ArgumentException>(() => client.GetReferrers("owner", ""));
}
}
public class TheGetAllPathsMethod
{
[Fact]
public void RequestsCorrectUrl()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoryTrafficClient(gitHubClient);
client.GetPaths("fake", "repo");
gitHubClient.Received().Repository.Traffic.GetPaths("fake", "repo");
}
[Fact]
public void RequestsCorrectUrlWithRepositoryId()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoryTrafficClient(gitHubClient);
client.GetPaths(1);
gitHubClient.Received().Repository.Traffic.GetPaths(1);
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ObservableRepositoryTrafficClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => client.GetPaths(null, "name"));
Assert.Throws<ArgumentNullException>(() => client.GetPaths("owner", null));
Assert.Throws<ArgumentException>(() => client.GetPaths("", "name"));
Assert.Throws<ArgumentException>(() => client.GetPaths("owner", ""));
}
}
public class TheGetClonesMethod
{
[Fact]
public void RequestsCorrectUrl()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoryTrafficClient(gitHubClient);
var per = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
client.GetClones("fake", "repo", per);
gitHubClient.Received().Repository.Traffic.GetClones("fake", "repo", per);
}
[Fact]
public void RequestsCorrectUrlWithRepositoryId()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoryTrafficClient(gitHubClient);
var per = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
client.GetClones(1, per);
gitHubClient.Received().Repository.Traffic.GetClones(1, per);
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ObservableRepositoryTrafficClient(Substitute.For<IGitHubClient>());
var per = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
Assert.Throws<ArgumentNullException>(() => client.GetClones(null, "name", per));
Assert.Throws<ArgumentNullException>(() => client.GetClones("owner", null, per));
Assert.Throws<ArgumentNullException>(() => client.GetClones("owner", "name", null));
Assert.Throws<ArgumentException>(() => client.GetClones("", "name", per));
Assert.Throws<ArgumentException>(() => client.GetClones("owner", "", per));
Assert.Throws<ArgumentNullException>(() => client.GetClones(1, null));
}
}
public class TheGetViewsMethod
{
[Fact]
public void RequestsCorrectUrl()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoryTrafficClient(gitHubClient);
var per = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
client.GetViews("fake", "repo", per);
gitHubClient.Received().Repository.Traffic.GetViews("fake", "repo", per);
}
[Fact]
public void RequestsCorrectUrlWithRepositoryId()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoryTrafficClient(gitHubClient);
var per = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
client.GetViews(1, per);
gitHubClient.Received().Repository.Traffic.GetViews(1, per);
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ObservableRepositoryTrafficClient(Substitute.For<IGitHubClient>());
var per = new RepositoryTrafficRequest(TrafficDayOrWeek.Day);
Assert.Throws<ArgumentNullException>(() => client.GetViews(null, "name", per));
Assert.Throws<ArgumentNullException>(() => client.GetViews("owner", null, per));
Assert.Throws<ArgumentNullException>(() => client.GetViews("owner", "name", null));
Assert.Throws<ArgumentException>(() => client.GetViews("", "name", per));
Assert.Throws<ArgumentException>(() => client.GetViews("owner", "", per));
Assert.Throws<ArgumentNullException>(() => client.GetViews(1, null));
}
}
}
}

View File

@@ -655,5 +655,13 @@ namespace Octokit
/// See the <a href="https://developer.github.com/v3/repos/invitations/">Repository Invitations API documentation</a> for more information. /// See the <a href="https://developer.github.com/v3/repos/invitations/">Repository Invitations API documentation</a> for more information.
/// </remarks> /// </remarks>
IRepositoryInvitationsClient Invitation { get; } IRepositoryInvitationsClient Invitation { get; }
/// <summary>
/// Access GitHub's Repository Traffic API
/// </summary>
/// <remarks>
/// Refer to the API documentation for more information: https://developer.github.com/v3/repos/traffic/
/// </remarks>
IRepositoryTrafficClient Traffic { get; }
} }
} }

View File

@@ -0,0 +1,82 @@
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Octokit
{
/// <summary>
/// A client for GitHub's Repository Traffic API.
/// </summary>
/// <remarks>
/// See the <a href="https://developer.github.com/v3/repos/traffic/">Repository Traffic API documentation</a> for more information.
/// </remarks>
public interface IRepositoryTrafficClient
{
/// <summary>
/// List the top 10 referrers over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-referrers</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
[ExcludeFromPaginationConventionTest]
Task<IReadOnlyList<RepositoryTrafficReferrer>> GetReferrers(string owner, string name);
/// <summary>
/// List the top 10 referrers over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-referrers</remarks>
/// <param name="repositoryId">The owner of the repository</param>
[ExcludeFromPaginationConventionTest]
Task<IReadOnlyList<RepositoryTrafficReferrer>> GetReferrers(long repositoryId);
/// <summary>
/// List the top 10 popular contents over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-paths</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
[ExcludeFromPaginationConventionTest]
Task<IReadOnlyList<RepositoryTrafficPath>> GetPaths(string owner, string name);
/// <summary>
/// List the top 10 popular contents over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-paths</remarks>
/// <param name="repositoryId">The owner of the repository</param>
[ExcludeFromPaginationConventionTest]
Task<IReadOnlyList<RepositoryTrafficPath>> GetPaths(long repositoryId);
/// <summary>
/// Get the total number of views and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#views</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="per">Breakdown per day or week</param>
Task<RepositoryTrafficViewSummary> GetViews(string owner, string name, RepositoryTrafficRequest per);
/// <summary>
/// Get the total number of views and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#views</remarks>
/// <param name="repositoryId">The owner of the repository</param>
/// <param name="per">Breakdown per day or week</param>
Task<RepositoryTrafficViewSummary> GetViews(long repositoryId, RepositoryTrafficRequest per);
/// <summary>
/// Get the total number of clones and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#clones</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="per">Breakdown per day or week</param>
Task<RepositoryTrafficCloneSummary> GetClones(string owner, string name, RepositoryTrafficRequest per);
/// <summary>
/// Get the total number of clones and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#clones</remarks>
/// <param name="repositoryId">The owner of the repository</param>
/// <param name="per">Breakdown per day or week</param>
Task<RepositoryTrafficCloneSummary> GetClones(long repositoryId, RepositoryTrafficRequest per);
}
}

View File

@@ -39,6 +39,7 @@ namespace Octokit
Page = new RepositoryPagesClient(apiConnection); Page = new RepositoryPagesClient(apiConnection);
Invitation = new RepositoryInvitationsClient(apiConnection); Invitation = new RepositoryInvitationsClient(apiConnection);
Branch = new RepositoryBranchesClient(apiConnection); Branch = new RepositoryBranchesClient(apiConnection);
Traffic = new RepositoryTrafficClient(apiConnection);
} }
/// <summary> /// <summary>
@@ -957,5 +958,13 @@ namespace Octokit
/// See the <a href="https://developer.github.com/v3/repos/invitations/">Repository Invitations API documentation</a> for more information. /// See the <a href="https://developer.github.com/v3/repos/invitations/">Repository Invitations API documentation</a> for more information.
/// </remarks> /// </remarks>
public IRepositoryInvitationsClient Invitation { get; private set; } public IRepositoryInvitationsClient Invitation { get; private set; }
/// <summary>
/// Access GitHub's Repository Traffic API
/// </summary>
/// <remarks>
/// Refer to the API documentation for more information: https://developer.github.com/v3/repos/traffic/
/// </remarks>
public IRepositoryTrafficClient Traffic { get; private set; }
} }
} }

View File

@@ -0,0 +1,118 @@
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Octokit
{
public class RepositoryTrafficClient : ApiClient, IRepositoryTrafficClient
{
public RepositoryTrafficClient(IApiConnection apiConnection) : base(apiConnection)
{
}
/// <summary>
/// List the top 10 popular contents over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-paths</remarks>
/// <param name="repositoryId">The owner of the repository</param>
public Task<IReadOnlyList<RepositoryTrafficPath>> GetPaths(long repositoryId)
{
return ApiConnection.GetAll<RepositoryTrafficPath>(ApiUrls.RepositoryTrafficPaths(repositoryId), AcceptHeaders.RepositoryTrafficApiPreview);
}
/// <summary>
/// List the top 10 popular contents over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-paths</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
public Task<IReadOnlyList<RepositoryTrafficPath>> GetPaths(string owner, string name)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
return ApiConnection.GetAll<RepositoryTrafficPath>(ApiUrls.RepositoryTrafficPaths(owner, name), AcceptHeaders.RepositoryTrafficApiPreview);
}
/// <summary>
/// List the top 10 referrers over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-referrers</remarks>
/// <param name="repositoryId">The owner of the repository</param>
public Task<IReadOnlyList<RepositoryTrafficReferrer>> GetReferrers(long repositoryId)
{
return ApiConnection.GetAll<RepositoryTrafficReferrer>(ApiUrls.RepositoryTrafficReferrers(repositoryId), AcceptHeaders.RepositoryTrafficApiPreview);
}
/// <summary>
/// List the top 10 referrers over the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#list-referrers</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
public Task<IReadOnlyList<RepositoryTrafficReferrer>> GetReferrers(string owner, string name)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
return ApiConnection.GetAll<RepositoryTrafficReferrer>(ApiUrls.RepositoryTrafficReferrers(owner, name), AcceptHeaders.RepositoryTrafficApiPreview);
}
/// <summary>
/// Get the total number of clones and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#clones</remarks>
/// <param name="repositoryId">The owner of the repository</param>
/// <param name="per">Breakdown per day or week</param>
public Task<RepositoryTrafficCloneSummary> GetClones(long repositoryId, RepositoryTrafficRequest per)
{
Ensure.ArgumentNotNull(per, "per");
return ApiConnection.Get<RepositoryTrafficCloneSummary>(ApiUrls.RepositoryTrafficClones(repositoryId), per.ToParametersDictionary(), AcceptHeaders.RepositoryTrafficApiPreview);
}
/// <summary>
/// Get the total number of clones and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#clones</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="per">Breakdown per day or week</param>
public Task<RepositoryTrafficCloneSummary> GetClones(string owner, string name, RepositoryTrafficRequest per)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNull(per, "per");
return ApiConnection.Get<RepositoryTrafficCloneSummary>(ApiUrls.RepositoryTrafficClones(owner, name), per.ToParametersDictionary(), AcceptHeaders.RepositoryTrafficApiPreview);
}
/// <summary>
/// Get the total number of views and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#views</remarks>
/// <param name="repositoryId">The owner of the repository</param>
/// <param name="per">Breakdown per day or week</param>
public Task<RepositoryTrafficViewSummary> GetViews(long repositoryId, RepositoryTrafficRequest per)
{
Ensure.ArgumentNotNull(per, "per");
return ApiConnection.Get<RepositoryTrafficViewSummary>(ApiUrls.RepositoryTrafficViews(repositoryId), per.ToParametersDictionary(), AcceptHeaders.RepositoryTrafficApiPreview);
}
/// <summary>
/// Get the total number of views and breakdown per day or week for the last 14 days
/// </summary>
/// <remarks>https://developer.github.com/v3/repos/traffic/#views</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="per">Breakdown per day or week</param>
public Task<RepositoryTrafficViewSummary> GetViews(string owner, string name, RepositoryTrafficRequest per)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNull(per, "per");
return ApiConnection.Get<RepositoryTrafficViewSummary>(ApiUrls.RepositoryTrafficViews(owner, name), per.ToParametersDictionary(), AcceptHeaders.RepositoryTrafficApiPreview);
}
}
}

View File

@@ -40,5 +40,7 @@ namespace Octokit
public const string PagesApiPreview = "application/vnd.github.mister-fantastic-preview+json"; public const string PagesApiPreview = "application/vnd.github.mister-fantastic-preview+json";
public const string IssueTimelineApiPreview = "application/vnd.github.mockingbird-preview"; public const string IssueTimelineApiPreview = "application/vnd.github.mockingbird-preview";
public const string RepositoryTrafficApiPreview = "application/vnd.github.spiderman-preview";
} }
} }

View File

@@ -3203,5 +3203,89 @@ namespace Octokit
{ {
return "user/repository_invitations/{0}".FormatUri(invitationId); return "user/repository_invitations/{0}".FormatUri(invitationId);
} }
/// <summary>
/// Returns the <see cref="Uri"/> for repository traffice referrers.
/// </summary>
/// <param name="owner">The owner of repo</param>
/// <param name="repo">The name of repo</param>
/// <returns>The <see cref="Uri"/> for repository traffic referrers.</returns>
public static Uri RepositoryTrafficReferrers(string owner, string repo)
{
return "repos/{0}/{1}/traffic/popular/referrers".FormatUri(owner, repo);
}
/// <summary>
/// Returns the <see cref="Uri"/> for repository traffice referrers.
/// </summary>
/// <param name="repositoryId">The id of the repository</param>
/// <returns>The <see cref="Uri"/> for repository traffic referrers.</returns>
public static Uri RepositoryTrafficReferrers(long repositoryId)
{
return "repositories/{0}/traffic/popular/referrers".FormatUri(repositoryId);
}
/// <summary>
/// Returns the <see cref="Uri"/> for repository traffice paths.
/// </summary>
/// <param name="owner">The owner of repo</param>
/// <param name="repo">The name of repo</param>
/// <returns>The <see cref="Uri"/> for repository traffic paths.</returns>
public static Uri RepositoryTrafficPaths(string owner, string repo)
{
return "repos/{0}/{1}/traffic/popular/paths".FormatUri(owner, repo);
}
/// <summary>
/// Returns the <see cref="Uri"/> for repository traffice paths.
/// </summary>
/// <param name="repositoryId">The id of the repository</param>
/// <returns>The <see cref="Uri"/> for repository traffic paths.</returns>
public static Uri RepositoryTrafficPaths(long repositoryId)
{
return "repositories/{0}/traffic/popular/paths".FormatUri(repositoryId);
}
/// <summary>
/// Returns the <see cref="Uri"/> for repository traffice views.
/// </summary>
/// <param name="owner">The owner of repo</param>
/// <param name="repo">The name of repo</param>
/// <returns>The <see cref="Uri"/> for repository traffic views.</returns>
public static Uri RepositoryTrafficViews(string owner, string repo)
{
return "repos/{0}/{1}/traffic/views".FormatUri(owner, repo);
}
/// <summary>
/// Returns the <see cref="Uri"/> for repository traffice views.
/// </summary>
/// <param name="repositoryId">The id of the repository</param>
/// <returns>The <see cref="Uri"/> for repository traffic views.</returns>
public static Uri RepositoryTrafficViews(long repositoryId)
{
return "repositories/{0}/traffic/views".FormatUri(repositoryId);
}
/// <summary>
/// Returns the <see cref="Uri"/> for repository traffice clones.
/// </summary>
/// <param name="owner">The owner of repo</param>
/// <param name="repo">The name of repo</param>
/// <returns>The <see cref="Uri"/> for repository traffic clones.</returns>
public static Uri RepositoryTrafficClones(string owner, string repo)
{
return "repos/{0}/{1}/traffic/clones".FormatUri(owner, repo);
}
/// <summary>
/// Returns the <see cref="Uri"/> for repository traffice clones.
/// </summary>
/// <param name="repositoryId">The id of the repository</param>
/// <returns>The <see cref="Uri"/> for repository traffic clones.</returns>
public static Uri RepositoryTrafficClones(long repositoryId)
{
return "repositories/{0}/traffic/clones".FormatUri(repositoryId);
}
} }
} }

View File

@@ -0,0 +1,23 @@
using System.Diagnostics;
using System.Globalization;
namespace Octokit
{
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class RepositoryTrafficRequest : RequestParameters
{
public RepositoryTrafficRequest() { }
public RepositoryTrafficRequest(TrafficDayOrWeek per)
{
Per = per;
}
public TrafficDayOrWeek Per { get; private set; }
internal string DebuggerDisplay
{
get { return string.Format(CultureInfo.InvariantCulture, "Per: {0}", Per); }
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using Octokit.Helpers;
using Octokit.Internal;
namespace Octokit
{
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class RepositoryTrafficCloneSummary
{
public RepositoryTrafficCloneSummary() { }
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "It's a property from the api.")]
public RepositoryTrafficCloneSummary(int count, int uniques, IReadOnlyList<RepositoryTrafficClone> clones)
{
Count = count;
Uniques = uniques;
Clones = clones;
}
public int Count { get; protected set; }
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "It's a property from the api.")]
public int Uniques { get; protected set; }
public IReadOnlyList<RepositoryTrafficClone> Clones { get; protected set; }
internal string DebuggerDisplay
{
get { return string.Format(CultureInfo.InvariantCulture, "Number: {0} Uniques: {1}", Count, Uniques); }
}
}
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class RepositoryTrafficClone
{
public RepositoryTrafficClone() { }
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "It's a property from the api.")]
public RepositoryTrafficClone(long timestamp, int count, int uniques)
{
TimestampAsUtcEpochSeconds = timestamp;
Count = count;
Uniques = uniques;
}
[Parameter(Key = "ignoreThisField")]
public DateTimeOffset Timestamp
{
get { return TimestampAsUtcEpochSeconds.FromUnixTime(); }
}
[Parameter(Key = "timestamp")]
public long TimestampAsUtcEpochSeconds { get; protected set; }
public int Count { get; protected set; }
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "It's a property from the api.")]
public int Uniques { get; protected set; }
internal string DebuggerDisplay
{
get { return string.Format(CultureInfo.InvariantCulture, "Number: {0} Uniques: {1}", Count, Uniques); }
}
}
public enum TrafficDayOrWeek
{
Day,
Week
}
}

View File

@@ -0,0 +1,35 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
namespace Octokit
{
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class RepositoryTrafficPath
{
public RepositoryTrafficPath() { }
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "It's a property from the api.")]
public RepositoryTrafficPath(string path, string title, int count, int uniques)
{
Path = path;
Title = title;
Count = count;
Uniques = uniques;
}
public string Path { get; protected set; }
public string Title { get; protected set; }
public int Count { get; protected set; }
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "It's a property from the api.")]
public int Uniques { get; protected set; }
internal string DebuggerDisplay
{
get { return string.Format(CultureInfo.InvariantCulture, "Path: {0}, Title: {1}", Path, Title); }
}
}
}

View File

@@ -0,0 +1,32 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
namespace Octokit
{
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class RepositoryTrafficReferrer
{
public RepositoryTrafficReferrer() { }
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "It's a property from the api.")]
public RepositoryTrafficReferrer(string referrer, int count, int uniques)
{
Referrer = referrer;
Count = count;
Uniques = uniques;
}
public string Referrer { get; protected set; }
public int Count { get; protected set; }
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "It's a property from the api.")]
public int Uniques { get; protected set; }
internal string DebuggerDisplay
{
get { return string.Format(CultureInfo.InvariantCulture, "Referrer: {0}, Count: {1}", Referrer, Count); }
}
}
}

View File

@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using Octokit.Helpers;
using Octokit.Internal;
namespace Octokit
{
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class RepositoryTrafficViewSummary
{
public RepositoryTrafficViewSummary() { }
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "It's a property from the api.")]
public RepositoryTrafficViewSummary(int count, int uniques, IReadOnlyList<RepositoryTrafficView> views)
{
Count = count;
Uniques = uniques;
Views = views;
}
public int Count { get; protected set; }
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "It's a property from the api.")]
public int Uniques { get; protected set; }
public IReadOnlyList<RepositoryTrafficView> Views { get; protected set; }
internal string DebuggerDisplay
{
get { return string.Format(CultureInfo.InvariantCulture, "Number: {0} Uniques: {1}", Count, Uniques); }
}
}
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class RepositoryTrafficView
{
public RepositoryTrafficView() { }
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "It's a property from the api.")]
public RepositoryTrafficView(long timestamp, int count, int uniques)
{
TimestampAsUtcEpochSeconds = timestamp;
Count = count;
Uniques = uniques;
}
[Parameter(Key = "ignoreThisField")]
public DateTimeOffset Timestamp
{
get { return TimestampAsUtcEpochSeconds.FromUnixTime(); }
}
[Parameter(Key = "timestamp")]
public long TimestampAsUtcEpochSeconds { get; protected set; }
public int Count { get; protected set; }
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", Justification = "It's a property from the api.")]
public int Uniques { get; protected set; }
internal string DebuggerDisplay
{
get { return string.Format(CultureInfo.InvariantCulture, "Timestamp: {0} Number: {1} Uniques: {2}", Timestamp, Count, Uniques); }
}
}
}

View File

@@ -494,6 +494,13 @@
<Compile Include="Clients\IRepositoryBranchesClient.cs" /> <Compile Include="Clients\IRepositoryBranchesClient.cs" />
<Compile Include="Clients\RepositoryBranchesClient.cs" /> <Compile Include="Clients\RepositoryBranchesClient.cs" />
<Compile Include="Models\Request\BranchProtectionUpdate.cs" /> <Compile Include="Models\Request\BranchProtectionUpdate.cs" />
<Compile Include="Models\Response\RepositoryTrafficClone.cs" />
<Compile Include="Models\Response\RepositoryTrafficPath.cs" />
<Compile Include="Models\Response\RepositoryTrafficReferrer.cs" />
<Compile Include="Models\Response\RepositoryTrafficView.cs" />
<Compile Include="Clients\IRepositoryTrafficClient.cs" />
<Compile Include="Models\Request\RepositoryTrafficRequest.cs" />
<Compile Include="Clients\RepositoryTrafficClient.cs" />
<Compile Include="Helpers\ExcludeFromPaginationConventionTest.cs" /> <Compile Include="Helpers\ExcludeFromPaginationConventionTest.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

View File

@@ -505,6 +505,13 @@
<Compile Include="Clients\IRepositoryBranchesClient.cs" /> <Compile Include="Clients\IRepositoryBranchesClient.cs" />
<Compile Include="Clients\RepositoryBranchesClient.cs" /> <Compile Include="Clients\RepositoryBranchesClient.cs" />
<Compile Include="Models\Request\BranchProtectionUpdate.cs" /> <Compile Include="Models\Request\BranchProtectionUpdate.cs" />
<Compile Include="Models\Response\RepositoryTrafficClone.cs" />
<Compile Include="Models\Response\RepositoryTrafficPath.cs" />
<Compile Include="Models\Response\RepositoryTrafficReferrer.cs" />
<Compile Include="Models\Response\RepositoryTrafficView.cs" />
<Compile Include="Clients\IRepositoryTrafficClient.cs" />
<Compile Include="Models\Request\RepositoryTrafficRequest.cs" />
<Compile Include="Clients\RepositoryTrafficClient.cs" />
<Compile Include="Helpers\ExcludeFromPaginationConventionTest.cs" /> <Compile Include="Helpers\ExcludeFromPaginationConventionTest.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />

View File

@@ -501,6 +501,13 @@
<Compile Include="Clients\IRepositoryBranchesClient.cs" /> <Compile Include="Clients\IRepositoryBranchesClient.cs" />
<Compile Include="Clients\RepositoryBranchesClient.cs" /> <Compile Include="Clients\RepositoryBranchesClient.cs" />
<Compile Include="Models\Request\BranchProtectionUpdate.cs" /> <Compile Include="Models\Request\BranchProtectionUpdate.cs" />
<Compile Include="Models\Response\RepositoryTrafficClone.cs" />
<Compile Include="Models\Response\RepositoryTrafficPath.cs" />
<Compile Include="Models\Response\RepositoryTrafficReferrer.cs" />
<Compile Include="Models\Response\RepositoryTrafficView.cs" />
<Compile Include="Clients\IRepositoryTrafficClient.cs" />
<Compile Include="Models\Request\RepositoryTrafficRequest.cs" />
<Compile Include="Clients\RepositoryTrafficClient.cs" />
<Compile Include="Helpers\ExcludeFromPaginationConventionTest.cs" /> <Compile Include="Helpers\ExcludeFromPaginationConventionTest.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.MonoTouch.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.MonoTouch.CSharp.targets" />

View File

@@ -491,6 +491,13 @@
<Compile Include="Clients\IRepositoryBranchesClient.cs" /> <Compile Include="Clients\IRepositoryBranchesClient.cs" />
<Compile Include="Clients\RepositoryBranchesClient.cs" /> <Compile Include="Clients\RepositoryBranchesClient.cs" />
<Compile Include="Models\Request\BranchProtectionUpdate.cs" /> <Compile Include="Models\Request\BranchProtectionUpdate.cs" />
<Compile Include="Models\Response\RepositoryTrafficClone.cs" />
<Compile Include="Models\Response\RepositoryTrafficPath.cs" />
<Compile Include="Models\Response\RepositoryTrafficReferrer.cs" />
<Compile Include="Models\Response\RepositoryTrafficView.cs" />
<Compile Include="Clients\IRepositoryTrafficClient.cs" />
<Compile Include="Models\Request\RepositoryTrafficRequest.cs" />
<Compile Include="Clients\RepositoryTrafficClient.cs" />
<Compile Include="Helpers\ExcludeFromPaginationConventionTest.cs" /> <Compile Include="Helpers\ExcludeFromPaginationConventionTest.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -498,6 +498,13 @@
<Compile Include="Models\Response\TimelineEventInfo.cs" /> <Compile Include="Models\Response\TimelineEventInfo.cs" />
<Compile Include="Clients\IRepositoryBranchesClient.cs" /> <Compile Include="Clients\IRepositoryBranchesClient.cs" />
<Compile Include="Clients\RepositoryBranchesClient.cs" /> <Compile Include="Clients\RepositoryBranchesClient.cs" />
<Compile Include="Models\Response\RepositoryTrafficClone.cs" />
<Compile Include="Models\Response\RepositoryTrafficPath.cs" />
<Compile Include="Models\Response\RepositoryTrafficReferrer.cs" />
<Compile Include="Models\Response\RepositoryTrafficView.cs" />
<Compile Include="Clients\IRepositoryTrafficClient.cs" />
<Compile Include="Models\Request\RepositoryTrafficRequest.cs" />
<Compile Include="Clients\RepositoryTrafficClient.cs" />
<Compile Include="Helpers\ExcludeFromPaginationConventionTest.cs" /> <Compile Include="Helpers\ExcludeFromPaginationConventionTest.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -65,6 +65,7 @@
<Compile Include="Clients\IPullRequestReviewCommentReactionsClient.cs" /> <Compile Include="Clients\IPullRequestReviewCommentReactionsClient.cs" />
<Compile Include="Clients\IRepositoryInvitationsClient.cs" /> <Compile Include="Clients\IRepositoryInvitationsClient.cs" />
<Compile Include="Clients\IRepositoryBranchesClient.cs" /> <Compile Include="Clients\IRepositoryBranchesClient.cs" />
<Compile Include="Clients\IRepositoryTrafficClient.cs" />
<Compile Include="Clients\IssueCommentReactionsClient.cs" /> <Compile Include="Clients\IssueCommentReactionsClient.cs" />
<Compile Include="Clients\IssueReactionsClient.cs" /> <Compile Include="Clients\IssueReactionsClient.cs" />
<Compile Include="Clients\IssueTimelineClient.cs" /> <Compile Include="Clients\IssueTimelineClient.cs" />
@@ -110,6 +111,7 @@
<Compile Include="Clients\RepositoryDeployKeysClient.cs" /> <Compile Include="Clients\RepositoryDeployKeysClient.cs" />
<Compile Include="Clients\RepositoryInvitationsClient.cs" /> <Compile Include="Clients\RepositoryInvitationsClient.cs" />
<Compile Include="Clients\RepositoryPagesClient.cs" /> <Compile Include="Clients\RepositoryPagesClient.cs" />
<Compile Include="Clients\RepositoryTrafficClient.cs" />
<Compile Include="Clients\UserAdministrationClient.cs" /> <Compile Include="Clients\UserAdministrationClient.cs" />
<Compile Include="Clients\UserGpgKeysClient.cs" /> <Compile Include="Clients\UserGpgKeysClient.cs" />
<Compile Include="Clients\UserKeysClient.cs" /> <Compile Include="Clients\UserKeysClient.cs" />
@@ -160,6 +162,7 @@
<Compile Include="Models\Request\RepositoryForksListRequest.cs" /> <Compile Include="Models\Request\RepositoryForksListRequest.cs" />
<Compile Include="Models\Request\RepositoryRequest.cs" /> <Compile Include="Models\Request\RepositoryRequest.cs" />
<Compile Include="Models\Request\Enterprise\SearchIndexingTarget.cs" /> <Compile Include="Models\Request\Enterprise\SearchIndexingTarget.cs" />
<Compile Include="Models\Request\RepositoryTrafficRequest.cs" />
<Compile Include="Models\Request\SearchIssuesRequestExclusions.cs" /> <Compile Include="Models\Request\SearchIssuesRequestExclusions.cs" />
<Compile Include="Models\Request\Signature.cs" /> <Compile Include="Models\Request\Signature.cs" />
<Compile Include="Models\Request\CreateFileRequest.cs" /> <Compile Include="Models\Request\CreateFileRequest.cs" />
@@ -219,6 +222,10 @@
<Compile Include="Models\Response\RepositoryInvitation.cs" /> <Compile Include="Models\Response\RepositoryInvitation.cs" />
<Compile Include="Models\Response\SourceInfo.cs" /> <Compile Include="Models\Response\SourceInfo.cs" />
<Compile Include="Models\Response\TimelineEventInfo.cs" /> <Compile Include="Models\Response\TimelineEventInfo.cs" />
<Compile Include="Models\Response\RepositoryTrafficClone.cs" />
<Compile Include="Models\Response\RepositoryTrafficPath.cs" />
<Compile Include="Models\Response\RepositoryTrafficReferrer.cs" />
<Compile Include="Models\Response\RepositoryTrafficView.cs" />
<Compile Include="Models\Response\UserRenameResponse.cs" /> <Compile Include="Models\Response\UserRenameResponse.cs" />
<Compile Include="Models\Response\ResourceRateLimit.cs" /> <Compile Include="Models\Response\ResourceRateLimit.cs" />
<Compile Include="Models\Response\RepositoryContent.cs" /> <Compile Include="Models\Response\RepositoryContent.cs" />