Add reactive notifications client

This commit is contained in:
Haacked
2013-10-19 17:10:00 -07:00
parent f4e50c071a
commit a98b53a246
10 changed files with 159 additions and 5 deletions

View File

@@ -0,0 +1,37 @@
using System;
using Octokit.Reactive.Internal;
namespace Octokit.Reactive.Clients
{
public class ObservableNotificationsClient : IObservableNotificationsClient
{
readonly IConnection _connection;
public ObservableNotificationsClient(IGitHubClient client)
{
Ensure.ArgumentNotNull(client, "client");
_connection = client.Connection;
}
/// <summary>
/// Retrieves all of the <see cref="Notification"/>s for the current user.
/// </summary>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="IObservable{Notification}"/> of <see cref="Notification"/>.</returns>
public IObservable<Notification> GetAllForCurrent()
{
return _connection.GetAndFlattenAllPages<Notification>(ApiUrls.Notifications());
}
/// <summary>
/// Retrieves all of the <see cref="Notification"/>s for the current user specific to the specified repository.
/// </summary>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="IObservable{Notification}"/> of <see cref="Notification"/>.</returns>
public IObservable<Notification> GetAllForRepository(string owner, string name)
{
return _connection.GetAndFlattenAllPages<Notification>(ApiUrls.Notifications(owner, name));
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Diagnostics.CodeAnalysis;
namespace Octokit.Reactive
{
public interface IObservableNotificationsClient
{
/// <summary>
/// Retrieves all of the <see cref="Notification"/>s for the current user.
/// </summary>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="IObservable{Notification}"/> of <see cref="Notification"/>.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
IObservable<Notification> GetAllForCurrent();
/// <summary>
/// Retrieves all of the <see cref="Notification"/>s for the current user specific to the specified repository.
/// </summary>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="IObservable{Notification}"/> of <see cref="Notification"/>.</returns>
IObservable<Notification> GetAllForRepository(string owner, string name);
}
}

View File

@@ -1,4 +1,4 @@
using Octokit.Internal; using Octokit.Reactive.Clients;
namespace Octokit.Reactive namespace Octokit.Reactive
{ {
@@ -13,6 +13,7 @@ namespace Octokit.Reactive
_gitHubClient = gitHubClient; _gitHubClient = gitHubClient;
Authorization = new ObservableAuthorizationsClient(gitHubClient); Authorization = new ObservableAuthorizationsClient(gitHubClient);
Miscellaneous = new ObservableMiscellaneousClient(gitHubClient.Miscellaneous); Miscellaneous = new ObservableMiscellaneousClient(gitHubClient.Miscellaneous);
Notification = new ObservableNotificationsClient(gitHubClient);
Organization = new ObservableOrganizationsClient(gitHubClient); Organization = new ObservableOrganizationsClient(gitHubClient);
Repository = new ObservableRepositoriesClient(gitHubClient); Repository = new ObservableRepositoriesClient(gitHubClient);
SshKey = new ObservableSshKeysClient(gitHubClient); SshKey = new ObservableSshKeysClient(gitHubClient);
@@ -27,6 +28,7 @@ namespace Octokit.Reactive
public IObservableAuthorizationsClient Authorization { get; private set; } public IObservableAuthorizationsClient Authorization { get; private set; }
public IObservableMiscellaneousClient Miscellaneous { get; private set; } public IObservableMiscellaneousClient Miscellaneous { get; private set; }
public IObservableNotificationsClient Notification { get; private set; }
public IObservableOrganizationsClient Organization { get; private set; } public IObservableOrganizationsClient Organization { get; private set; }
public IObservableRepositoriesClient Repository { get; private set; } public IObservableRepositoriesClient Repository { get; private set; }
public IObservableReleasesClient Release { get; private set; } public IObservableReleasesClient Release { get; private set; }

View File

@@ -85,6 +85,7 @@
<Compile Include="..\SolutionInfo.cs"> <Compile Include="..\SolutionInfo.cs">
<Link>Properties\SolutionInfo.cs</Link> <Link>Properties\SolutionInfo.cs</Link>
</Compile> </Compile>
<Compile Include="Clients\ObservableNotificationsClient.cs" />
<Compile Include="Clients\ObservableAuthorizationsClient.cs" /> <Compile Include="Clients\ObservableAuthorizationsClient.cs" />
<Compile Include="Clients\ObservableMiscellaneousClient.cs" /> <Compile Include="Clients\ObservableMiscellaneousClient.cs" />
<Compile Include="Clients\ObservableOrganizationsClient.cs" /> <Compile Include="Clients\ObservableOrganizationsClient.cs" />
@@ -92,6 +93,7 @@
<Compile Include="Clients\ObservableRepositoriesClient.cs" /> <Compile Include="Clients\ObservableRepositoriesClient.cs" />
<Compile Include="Clients\ObservableSshKeysClient.cs" /> <Compile Include="Clients\ObservableSshKeysClient.cs" />
<Compile Include="Clients\ObservableUsersClient.cs" /> <Compile Include="Clients\ObservableUsersClient.cs" />
<Compile Include="IObservableNotificationsClient.cs" />
<Compile Include="Helpers\AuthorizationExtensions.cs" /> <Compile Include="Helpers\AuthorizationExtensions.cs" />
<Compile Include="Helpers\ConnectionExtensions.cs" /> <Compile Include="Helpers\ConnectionExtensions.cs" />
<Compile Include="Helpers\ObservableExtensions.cs" /> <Compile Include="Helpers\ObservableExtensions.cs" />

View File

@@ -0,0 +1,39 @@
using System;
using NSubstitute;
using Xunit;
namespace Octokit.Tests.Clients
{
public class NotificationsClientTests
{
public class TheGetAllForCurrentMethod
{
[Fact]
public void RequestsCorrectUrl()
{
var endpoint = new Uri("/notifications", UriKind.Relative);
var connection = Substitute.For<IApiConnection>();
var client = new NotificationsClient(connection);
client.GetAllForCurrent();
connection.Received().GetAll<Notification>(endpoint);
}
}
public class TheGetAllForRepository
{
[Fact]
public void RequestsCorrectUrl()
{
var endpoint = new Uri("/repos/banana/split/notifications", UriKind.Relative);
var connection = Substitute.For<IApiConnection>();
var client = new NotificationsClient(connection);
client.GetAllForRepository("banana", "split");
connection.Received().GetAll<Notification>(endpoint);
}
}
}
}

View File

@@ -60,6 +60,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Authentication\CredentialsTests.cs" /> <Compile Include="Authentication\CredentialsTests.cs" />
<Compile Include="Clients\NotificationsClientTests.cs" />
<Compile Include="Clients\ReleasesClientTests.cs" /> <Compile Include="Clients\ReleasesClientTests.cs" />
<Compile Include="Clients\SshKeysClientTests.cs" /> <Compile Include="Clients\SshKeysClientTests.cs" />
<Compile Include="Exceptions\ApiExceptionTests.cs" /> <Compile Include="Exceptions\ApiExceptionTests.cs" />

View File

@@ -52,6 +52,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="Authentication\CredentialsTests.cs" /> <Compile Include="Authentication\CredentialsTests.cs" />
<Compile Include="Clients\MiscellaneousClientTests.cs" /> <Compile Include="Clients\MiscellaneousClientTests.cs" />
<Compile Include="Clients\NotificationsClientTests.cs" />
<Compile Include="Clients\ReleasesClientTests.cs" /> <Compile Include="Clients\ReleasesClientTests.cs" />
<Compile Include="Clients\SshKeysClientTests.cs" /> <Compile Include="Clients\SshKeysClientTests.cs" />
<Compile Include="Exceptions\ApiExceptionTests.cs" /> <Compile Include="Exceptions\ApiExceptionTests.cs" />

View File

@@ -10,9 +10,24 @@ namespace Octokit
{ {
} }
public async Task<IReadOnlyCollection<Notification>> ListNotifications() /// <summary>
/// Retrieves all of the <see cref="Notification"/>s for the current user.
/// </summary>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="IReadOnlyPagedCollection{Notification}"/> of <see cref="Notification"/>.</returns>
public async Task<IReadOnlyCollection<Notification>> GetAllForCurrent()
{ {
return await Client.GetAll<Notification>(new Uri("/notifications", UriKind.Relative)); return await Client.GetAll<Notification>(ApiUrls.Notifications());
}
/// <summary>
/// Retrieves all of the <see cref="Notification"/>s for the current user specific to the specified repository.
/// </summary>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="IReadOnlyPagedCollection{Notification}"/> of <see cref="Notification"/>.</returns>
public async Task<IReadOnlyCollection<Notification>> GetAllForRepository(string owner, string name)
{
return await Client.GetAll<Notification>(ApiUrls.Notifications(owner, name));
} }
} }
} }

View File

@@ -12,7 +12,7 @@ namespace Octokit
static readonly Uri _currentUserSshKeys = new Uri("/user/keys", UriKind.Relative); static readonly Uri _currentUserSshKeys = new Uri("/user/keys", UriKind.Relative);
static readonly Uri _currentUserEmailsEndpoint = new Uri("/user/emails", UriKind.Relative); static readonly Uri _currentUserEmailsEndpoint = new Uri("/user/emails", UriKind.Relative);
static readonly Uri _currentUserAuthorizationsEndpoint = new Uri("/authorizations", UriKind.Relative); static readonly Uri _currentUserAuthorizationsEndpoint = new Uri("/authorizations", UriKind.Relative);
static readonly Uri _currentUserNotificationsEndpoint = new Uri("/notifications", UriKind.Relative);
/// <summary> /// <summary>
/// Returns the <see cref="Uri"/> that returns all of the repositories for the currently logged in user in /// Returns the <see cref="Uri"/> that returns all of the repositories for the currently logged in user in
@@ -111,5 +111,24 @@ namespace Octokit
{ {
return _currentUserAuthorizationsEndpoint; return _currentUserAuthorizationsEndpoint;
} }
/// <summary>
/// Returns the <see cref="Uri"/> that returns all of the notifications for the currently logged in user.
/// </summary>
/// <returns></returns>
public static Uri Notifications()
{
return _currentUserNotificationsEndpoint;
}
/// <summary>
/// Returns the <see cref="Uri"/> that returns all of the notifications for the currently logged in user
/// specific to the repository.
/// </summary>
/// <returns></returns>
public static Uri Notifications(string owner, string name)
{
return "/repos/{0}/{1}/notifications".FormatUri(owner, name);
}
} }
} }

View File

@@ -1,10 +1,24 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Octokit namespace Octokit
{ {
public interface INotificationsClient public interface INotificationsClient
{ {
Task<IReadOnlyCollection<Notification>> ListNotifications(); /// <summary>
/// Retrieves all of the <see cref="Notification"/>s for the current user.
/// </summary>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="IReadOnlyPagedCollection{Notification}"/> of <see cref="Notification"/>.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
Task<IReadOnlyCollection<Notification>> GetAllForCurrent();
/// <summary>
/// Retrieves all of the <see cref="Notification"/>s for the current user specific to the specified repository.
/// </summary>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated.</exception>
/// <returns>A <see cref="IReadOnlyPagedCollection{Notification}"/> of <see cref="Notification"/>.</returns>
Task<IReadOnlyCollection<Notification>> GetAllForRepository(string owner, string name);
} }
} }