Merge branch 'master' into shiftkey/revive-pull-requests

This commit is contained in:
Brendan Forster
2014-02-18 15:40:08 +11:00
283 changed files with 44554 additions and 21862 deletions

View File

@@ -3,7 +3,7 @@
public interface IObservableActivitiesClient public interface IObservableActivitiesClient
{ {
IObservableEventsClient Events { get; } IObservableEventsClient Events { get; }
IObservableWatchedClient Watched { get; } IObservableWatchedClient Watching { get; }
IObservableStarredClient Starred { get; } IObservableStarredClient Starring { get; }
} }
} }

View File

@@ -2,7 +2,7 @@
namespace Octokit.Reactive namespace Octokit.Reactive
{ {
public interface IObservableBlobClient public interface IObservableBlobsClient
{ {
/// <summary> /// <summary>
/// Gets a single Blob by SHA. /// Gets a single Blob by SHA.

View File

@@ -0,0 +1,36 @@
using System;
using System.Reactive.Threading.Tasks;
using Octokit.Reactive.Internal;
namespace Octokit.Reactive.Clients
{
public interface IObservableDeploymentStatusClient
{
/// <summary>
/// Gets all the statuses for the given deployment. Any user with pull access to a repository can
/// view deployments.
/// </summary>
/// <remarks>
/// http://developer.github.com/v3/repos/deployments/#list-deployment-statuses
/// </remarks>
/// <param name="owner">The owner of the repository.</param>
/// <param name="name">The name of the repository.</param>
/// <param name="deploymentId">The id of the deployment.</param>
/// <returns>All deployment statuses for the given deployment.</returns>
IObservable<DeploymentStatus> GetAll(string owner, string name, int deploymentId);
/// <summary>
/// Creates a new status for the given deployment. Users with push access can create deployment
/// statuses for a given deployment.
/// </summary>
/// <remarks>
/// http://developer.github.com/v3/repos/deployments/#create-a-deployment-status
/// </remarks>
/// <param name="owner">The owner of the repository.</param>
/// <param name="name">The name of the repository.</param>
/// <param name="deploymentId">The id of the deployment.</param>
/// <param name="newDeploymentStatus">The new deployment status to create.</param>
/// <returns></returns>
IObservable<DeploymentStatus> Create(string owner, string name, int deploymentId, NewDeploymentStatus newDeploymentStatus);
}
}

View File

@@ -0,0 +1,32 @@
using System;
namespace Octokit.Reactive.Clients
{
public interface IObservableDeploymentsClient
{
/// <summary>
/// Gets all the deployments for the specified repository. Any user with pull access
/// to a repository can view deployments.
/// </summary>
/// <remarks>
/// http://developer.github.com/v3/repos/deployments/#list-deployments
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns>All the <see cref="Deployment"/>s for the specified repository.</returns>
IObservable<Deployment> GetAll(string owner, string name);
/// <summary>
/// Creates a new deployment for the specified repository.
/// Users with push access can create a deployment for a given ref.
/// </summary>
/// <remarks>
/// http://developer.github.com/v3/repos/deployments/#create-a-deployment
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="newDeployment">A <see cref="NewDeployment"/> instance describing the new deployment to create</param>
/// <returns>The created <see cref="Deployment"></returns>
IObservable<Deployment> Create(string owner, string name, NewDeployment newDeployment);
}
}

View File

@@ -5,10 +5,10 @@
/// </summary> /// </summary>
public interface IObservableGitDatabaseClient public interface IObservableGitDatabaseClient
{ {
IObservableBlobClient Blob { get; set; } IObservableBlobsClient Blob { get; }
IObservableTagsClient Tag { get; set; } IObservableTagsClient Tag { get; }
IObservableTreesClient Tree { get; set; } IObservableTreesClient Tree { get; }
IObservableCommitsClient Commit { get; set; } IObservableCommitsClient Commit { get; }
IObservableReferencesClient Reference { get; set; } IObservableReferencesClient Reference { get; }
} }
} }

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Reactive;
namespace Octokit.Reactive namespace Octokit.Reactive
{ {
@@ -57,5 +58,15 @@ namespace Octokit.Reactive
/// <param name="commentUpdate">The modified comment</param> /// <param name="commentUpdate">The modified comment</param>
/// <returns></returns> /// <returns></returns>
IObservable<IssueComment> Update(string owner, string name, int number, string commentUpdate); IObservable<IssueComment> Update(string owner, string name, int number, string commentUpdate);
/// <summary>
/// Deletes the specified Issue Comment
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#delete-a-comment</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="number">The comment number</param>
/// <returns></returns>
IObservable<Unit> Delete(string owner, string name, int number);
} }
} }

View File

@@ -5,6 +5,9 @@ namespace Octokit.Reactive
{ {
public interface IObservableIssuesClient public interface IObservableIssuesClient
{ {
/// <summary>
/// Client for managing assignees.
/// </summary>
IObservableAssigneesClient Assignee { get; } IObservableAssigneesClient Assignee { get; }
/// <summary> /// <summary>
@@ -12,6 +15,23 @@ namespace Octokit.Reactive
/// </summary> /// </summary>
IObservableMilestonesClient Milestone { get; } IObservableMilestonesClient Milestone { get; }
/// <summary>
/// Client for reading various event information associated with issues/pull requests.
/// This is useful both for display on issue/pull request information pages and also to
/// determine who should be notified of comments.
/// </summary>
IObservableIssuesEventsClient Events { get; }
/// <summary>
/// Client for managing labels.
/// </summary>
IObservableIssuesLabelsClient Labels { get; }
/// <summary>
/// Client for managing comments.
/// </summary>
IObservableIssueCommentsClient Comment { get; }
/// <summary> /// <summary>
/// Gets a single Issue by number. /// Gets a single Issue by number.
/// </summary> /// </summary>

View File

@@ -0,0 +1,146 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Reactive;
namespace Octokit.Reactive
{
public interface IObservableIssuesLabelsClient
{
/// <summary>
/// Gets all labels for the issue.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#list-labels-on-an-issue">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="number">The number of the issue</param>
/// <returns>The list of labels</returns>
IObservable<Label> GetForIssue(string owner, string repo, int number);
/// <summary>
/// Gets all labels for the repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <returns>The list of labels</returns>
IObservable<Label> GetForRepository(string owner, string repo);
/// <summary>
/// Gets a single Label by name.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#get-a-single-label">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="name">The name of the label</param>
/// <returns>The label</returns>
[SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get",
Justification = "Method makes a network request")]
IObservable<Label> Get(string owner, string repo, string name);
/// <summary>
/// Deletes a label.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#delete-a-label">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="name">The name of the label</param>
/// <returns></returns>
IObservable<Unit> Delete(string owner, string repo, string name);
/// <summary>
/// Creates a label.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#create-a-label">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="newLabel">The data for the label to be created</param>
/// <returns>The created label</returns>
IObservable<Label> Create(string owner, string repo, NewLabel newLabel);
/// <summary>
/// Updates a label.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#update-a-label">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="name">The name of the label</param>
/// <param name="labelUpdate">The data for the label to be updated</param>
/// <returns>The updated label</returns>
IObservable<Label> Update(string owner, string repo, string name, LabelUpdate labelUpdate);
/// <summary>
/// Adds a label to an issue
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#add-labels-to-an-issue">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="number">The number of the issue</param>
/// <param name="labels">The names of the labels to add</param>
/// <returns></returns>
IObservable<Label> AddToIssue(string owner, string repo, int number, string[] labels);
/// <summary>
/// Removes a label from an issue
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="number">The number of the issue</param>
/// <param name="label">The name of the label to remove</param>
/// <returns></returns>
IObservable<Unit> RemoveFromIssue(string owner, string repo, int number, string label);
/// <summary>
/// Replaces all labels on the specified issues with the provided labels
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="number">The number of the issue</param>
/// <param name="labels">The names of the labels to set</param>
/// <returns></returns>
IObservable<Label> ReplaceAllForIssue(string owner, string repo, int number, string[] labels);
/// <summary>
/// Removes all labels from an issue
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#remove-all-labels-from-an-issue">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="number">The number of the issue</param>
/// <returns></returns>
IObservable<Unit> RemoveAllFromIssue(string owner, string repo, int number);
/// <summary>
/// Gets labels for every issue in a milestone
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="number">The number of the milestone</param>
/// <returns></returns>
IObservable<Label> GetForMilestone(string owner, string repo, int number);
}
}

View File

@@ -13,7 +13,7 @@ namespace Octokit.Reactive
/// <summary> /// <summary>
/// Returns a client to manage teams for an organization. /// Returns a client to manage teams for an organization.
/// </summary> /// </summary>
IObservableOrganizationTeamsClient Teams { get; } IObservableTeamsClient Team { get; }
/// <summary> /// <summary>
/// Returns the specified organization. /// Returns the specified organization.

View File

@@ -41,7 +41,7 @@ namespace Octokit.Reactive
/// <param name="name">The name of the repository</param> /// <param name="name">The name of the repository</param>
/// <param name="subNamespace">The sub-namespace to get references for</param> /// <param name="subNamespace">The sub-namespace to get references for</param>
/// <returns></returns> /// <returns></returns>
IObservable<Reference> GetAll(string owner, string name, string subNamespace); IObservable<Reference> GetAllForSubNamespace(string owner, string name, string subNamespace);
/// <summary> /// <summary>
/// Creates a reference for a given repository /// Creates a reference for a given repository

View File

@@ -1,11 +1,138 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Reactive;
namespace Octokit.Reactive namespace Octokit.Reactive
{ {
public interface IObservableReleasesClient public interface IObservableReleasesClient
{ {
/// <summary>
/// Gets all <see cref="Release"/>s for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#list-releases-for-a-repository">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>The list of <see cref="Release"/>s for the specified repository.</returns>
IObservable<Release> GetAll(string owner, string name); IObservable<Release> GetAll(string owner, string name);
/// <summary>
/// Gets a single <see cref="Release"/> for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#get-a-single-release">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="number">The id of the release</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>The <see cref="Release"/> specified by the id</returns>
[SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", Justification = "Method makes a network request")]
IObservable<Release> Get(string owner, string name, int number);
/// <summary>
/// Creates a new <see cref="Release"/> for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#create-a-release">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="data">A description of the release to create</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>The created <see cref="Release"/>.</returns>
IObservable<Release> CreateRelease(string owner, string name, ReleaseUpdate data); IObservable<Release> CreateRelease(string owner, string name, ReleaseUpdate data);
/// <summary>
/// Edits an existing <see cref="Release"/> for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#edit-a-release">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="data">A description of the release to edit</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>The updated <see cref="Release"/>.</returns>
IObservable<Release> EditRelease(string owner, string name, ReleaseUpdate data);
/// <summary>
/// Deletes an existing <see cref="Release"/> for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#delete-a-release">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="number">The id of the release to delete</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns></returns>
IObservable<Unit> DeleteRelease(string owner, string name, int number);
/// <summary>
/// Gets all <see cref="ReleaseAsset"/> for the specified release of the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#list-assets-for-a-release">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="number">The id of the <see cref="Release"/>.</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>The list of <see cref="ReleaseAsset"/> for the specified release of the specified repository.</returns>
IObservable<ReleaseAsset> GetAssets(string owner, string name, int number);
/// <summary>
/// Uploads a <see cref="ReleaseAsset"/> for the specified release.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#upload-a-release-asset">API documentation</a> for more information.
/// </remarks>
/// <param name="release">The <see cref="Release"/> to attach the uploaded asset to</param>
/// <param name="data">Description of the asset with its data</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>The created <see cref="ReleaseAsset"/>.</returns>
IObservable<ReleaseAsset> UploadAsset(Release release, ReleaseAssetUpload data); IObservable<ReleaseAsset> UploadAsset(Release release, ReleaseAssetUpload data);
/// <summary>
/// Gets the specified <see cref="ReleaseAsset"/> for the specified release of the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#get-a-single-release-asset">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="releaseId">The id of the <see cref="Release"/></param>
/// <param name="assetId">The id of the <see cref="ReleaseAsset"/></param>
/// <returns>The <see cref="ReleaseAsset"/> specified by the asset id.</returns>
IObservable<ReleaseAsset> GetAsset(string owner, string name, int releaseId, int assetId);
/// <summary>
/// Edits the <see cref="ReleaseAsset"/> for the specified release of the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#edit-a-release-asset">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="releaseId">The id of the <see cref="Release"/></param>
/// <param name="assetId">The id of the <see cref="ReleaseAsset"/></param>
/// <param name="data">Description of the asset with its amended data</param>
/// <returns>The edited <see cref="ReleaseAsset"/>.</returns>
IObservable<ReleaseAsset> EditAsset(string owner, string name, int releaseId, int assetId, ReleaseAssetUpdate data);
/// <summary>
/// Deletes the specified <see cref="ReleaseAsset"/> from the specified repository
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#delete-a-release-asset">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="number">The id of the <see cref="ReleaseAsset"/>.</param>
/// <returns></returns>
IObservable<Unit> DeleteAsset(string owner, string name, int number);
} }
} }

View File

@@ -10,35 +10,35 @@ namespace Octokit.Reactive
/// Gets all the available collaborators on this repo. /// Gets all the available collaborators on this repo.
/// </summary> /// </summary>
/// <param name="owner">The owner of the repository</param> /// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param> /// <param name="repo">The name of the repository</param>
/// <returns></returns> /// <returns></returns>
IObservable<User> GetAll(string owner, string name); IObservable<User> GetAll(string owner, string repo);
/// <summary> /// <summary>
/// Checks to see if a user is an assignee for a repository. /// Checks to see if a user is an assignee for a repository.
/// </summary> /// </summary>
/// <param name="owner">The owner of the repository</param> /// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param> /// <param name="repo">The name of the repository</param>
/// <param name="user">Username of the prospective collaborator</param> /// <param name="user">Username of the prospective collaborator</param>
/// <returns></returns> /// <returns></returns>
IObservable<bool> IsCollaborator(string owner, string name, string user); IObservable<bool> IsCollaborator(string owner, string repo, string user);
/// <summary> /// <summary>
/// Adds a user as a collaborator to a repository. /// Adds a user as a collaborator to a repository.
/// </summary> /// </summary>
/// <param name="owner">The owner of the repository</param> /// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param> /// <param name="repo">The name of the repository</param>
/// <param name="user">Username of the prospective collaborator</param> /// <param name="user">Username of the prospective collaborator</param>
/// <returns></returns> /// <returns></returns>
IObservable<Unit> Add(string owner, string name, string user); IObservable<Unit> Add(string owner, string repo, string user);
/// <summary> /// <summary>
/// Removes a user as a collaborator for a repository. /// Removes a user as a collaborator for a repository.
/// </summary> /// </summary>
/// <param name="owner">The owner of the repository</param> /// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param> /// <param name="repo">The name of the repository</param>
/// <param name="user">Username of the prospective collaborator</param> /// <param name="user">Username of the prospective collaborator</param>
/// <returns></returns> /// <returns></returns>
IObservable<Unit> Delete(string owner, string name, string user); IObservable<Unit> Delete(string owner, string repo, string user);
} }
} }

View File

@@ -98,5 +98,101 @@ namespace Octokit.Reactive
/// that announced this feature. /// that announced this feature.
/// </remarks> /// </remarks>
IObservableCommitStatusClient CommitStatus { get; } IObservableCommitStatusClient CommitStatus { get; }
/// <summary>
/// Gets all the branches for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#list-branches">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>All <see cref="T:Octokit.Branch"/>es of the repository</returns>
IObservable<Branch> GetAllBranches(string owner, string name);
/// <summary>
/// Gets all contributors for the specified repository. Does not include anonymous contributors.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#list-contributors">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns>All contributors of the repository.</returns>
IObservable<User> GetAllContributors(string owner, string name);
/// <summary>
/// Gets all contributors for the specified repository. With the option to include anonymous contributors.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#list-contributors">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="includeAnonymous">True if anonymous contributors should be included in result; Otherwise false</param>
/// <returns>All contributors of the repository.</returns>
IObservable<User> GetAllContributors(string owner, string name, bool includeAnonymous);
/// <summary>
/// Gets all languages for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#list-languages">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns>All languages used in the repository and the number of bytes of each language.</returns>
IObservable<RepositoryLanguage> GetAllLanguages(string owner, string name);
/// <summary>
/// Gets all teams for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#list-teams">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns>All <see cref="T:Octokit.Team"/>s associated with the repository</returns>
IObservable<Team> GetAllTeams(string owner, string name);
/// <summary>
/// Gets all tags for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#list-tags">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns>All of the repositorys tags.</returns>
IObservable<RepositoryTag> GetAllTags(string owner, string name);
/// <summary>
/// Gets the specified branch.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#get-branch">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repositoryName">The name of the repository</param>
/// <param name="branchName">The name of the branch</param>
/// <returns>The specified <see cref="T:Octokit.Branch"/></returns>
IObservable<Branch> GetBranch(string owner, string repositoryName, string branchName);
/// <summary>
/// Updates the specified repository with the values given in <paramref name="update"/>
/// </summary>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="update">New values to update the repository with</param>
/// <returns>The updated <see cref="T:Octokit.Repository"/></returns>
IObservable<Repository> Edit(string owner, string name, RepositoryUpdate update);
/// A client for GitHub's Repo Collaborators.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/collaborators/">Collaborators API documentation</a> for more details
/// </remarks>
IObservableRepoCollaboratorsClient RepoCollaborators { get; }
} }
} }

View File

@@ -13,32 +13,32 @@ namespace Octokit.Reactive
/// search repos /// search repos
/// http://developer.github.com/v3/search/#search-repositories /// http://developer.github.com/v3/search/#search-repositories
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="search"></param>
/// <returns>List of repositories</returns> /// <returns>List of repositories</returns>
IObservable<Repository> SearchRepo(SearchRepositoriesRequest request); IObservable<Repository> SearchRepo(SearchRepositoriesRequest search);
/// <summary> /// <summary>
/// search users /// search users
/// http://developer.github.com/v3/search/#search-users /// http://developer.github.com/v3/search/#search-users
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="search"></param>
/// <returns>List of users</returns> /// <returns>List of users</returns>
IObservable<User> SearchUsers(SearchUsersRequest request); IObservable<User> SearchUsers(SearchUsersRequest search);
/// <summary> /// <summary>
/// search issues /// search issues
/// http://developer.github.com/v3/search/#search-issues /// http://developer.github.com/v3/search/#search-issues
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="search"></param>
/// <returns>List of issues</returns> /// <returns>List of issues</returns>
IObservable<Issue> SearchIssues(SearchIssuesRequest request); IObservable<Issue> SearchIssues(SearchIssuesRequest search);
/// <summary> /// <summary>
/// search code /// search code
/// http://developer.github.com/v3/search/#search-code /// http://developer.github.com/v3/search/#search-code
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="search"></param>
/// <returns>List of files</returns> /// <returns>List of files</returns>
IObservable<SearchCode> SearchCode(SearchCodeRequest request); IObservable<SearchCode> SearchCode(SearchCodeRequest search);
} }
} }

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
namespace Octokit.Reactive
{
public interface IObservableStatisticsClient
{
/// <summary>
/// Returns a list of <see cref="Contributor"/> for the given repository
/// </summary>
/// <param name="owner">The owner of the repository</param>
/// <param name="repositoryName">The name of the repository</param>
/// <returns>A list of <see cref="Contributor"/></returns>
IObservable<IEnumerable<Contributor>> GetContributors(string owner, string repositoryName);
}
}

View File

@@ -1,5 +1,4 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
using System.Reactive; using System.Reactive;
namespace Octokit.Reactive namespace Octokit.Reactive
@@ -10,7 +9,7 @@ namespace Octokit.Reactive
/// <remarks> /// <remarks>
/// See the <a href="http://developer.github.com/v3/orgs/teams/">Orgs API documentation</a> for more information. /// See the <a href="http://developer.github.com/v3/orgs/teams/">Orgs API documentation</a> for more information.
/// </remarks> /// </remarks>
public interface IObservableOrganizationTeamsClient public interface IObservableTeamsClient
{ {
/// <summary> /// <summary>
/// Returns all <see cref="Team" />s for the current org. /// Returns all <see cref="Team" />s for the current org.

View File

@@ -0,0 +1,35 @@
using System;
using System.Diagnostics.CodeAnalysis;
namespace Octokit.Reactive
{
/// <summary>
/// A client for GitHub's User Emails API.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/users/emails/">User Emails API documentation</a> for more information.
/// </remarks>
public interface IObservableUserEmailsClient
{
/// <summary>
/// Gets all email addresses for the authenticated user.
/// </summary>
/// <remarks>
/// http://developer.github.com/v3/users/emails/#list-email-addresses-for-a-user
/// </remarks>
/// <returns>The <see cref="EmailAddress"/>es for the authenticated user.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
IObservable<EmailAddress> GetAll();
/// <summary>
/// Adds email addresses for the authenticated user.
/// </summary>
/// <remarks>
/// http://developer.github.com/v3/users/emails/#add-email-addresses
/// </remarks>
/// <param name="emailAddresses">The email addresses to add.</param>
/// <returns>Returns the added <see cref="EmailAddress"/>es.</returns>
IObservable<string> Add(params string[] emailAddresses);
}
}

View File

@@ -29,10 +29,11 @@ namespace Octokit.Reactive
IObservable<User> Update(UserUpdate user); IObservable<User> Update(UserUpdate user);
/// <summary> /// <summary>
/// Returns emails for the current user. /// A client for GitHub's User Followers API
/// </summary> /// </summary>
/// <returns></returns> /// <remarks>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")] /// See the <a href="http://developer.github.com/v3/users/followers/">Followers API documentation</a> for more information.
IObservable<EmailAddress> GetEmails(); ///</remarks>
IObservableFollowersClient Followers { get; }
} }
} }

View File

@@ -37,7 +37,7 @@ namespace Octokit.Reactive
/// <param name="name">The name of the repository</param> /// <param name="name">The name of the repository</param>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated</exception> /// <exception cref="AuthorizationException">Thrown if the client is not authenticated</exception>
/// <returns>A <c>bool</c> representing the success of the operation</returns> /// <returns>A <c>bool</c> representing the success of the operation</returns>
IObservable<bool> CheckStarred(string owner, string name); IObservable<bool> CheckWatched(string owner, string name);
/// <summary> /// <summary>
/// Stars a repository for the authenticated user. /// Stars a repository for the authenticated user.

View File

@@ -7,13 +7,13 @@
Ensure.ArgumentNotNull(client, "client"); Ensure.ArgumentNotNull(client, "client");
Events = new ObservableEventsClient(client); Events = new ObservableEventsClient(client);
Watched = new ObservableWatchedClient(client); Watching = new ObservableWatchedClient(client);
Starred = new ObservableStarredClient(client); Starring = new ObservableStarredClient(client);
} }
public IObservableEventsClient Events { get; private set; } public IObservableEventsClient Events { get; private set; }
public IObservableWatchedClient Watched { get; private set; } public IObservableWatchedClient Watching { get; private set; }
public IObservableStarredClient Starred { get; private set; } public IObservableStarredClient Starring { get; private set; }
} }
} }

View File

@@ -3,7 +3,7 @@ using System.Reactive.Threading.Tasks;
namespace Octokit.Reactive namespace Octokit.Reactive
{ {
public class ObservableBlobClient : IObservableBlobClient public class ObservableBlobClient : IObservableBlobsClient
{ {
readonly IBlobsClient _client; readonly IBlobsClient _client;

View File

@@ -0,0 +1,59 @@
using Octokit.Reactive.Internal;
using System;
using System.Reactive.Threading.Tasks;
namespace Octokit.Reactive.Clients
{
public class ObservableDeploymentStatusClient : IObservableDeploymentStatusClient
{
const string acceptsHeader = "application/vnd.github.cannonball-preview+json";
private IDeploymentStatusClient _client;
private IConnection _connection;
public ObservableDeploymentStatusClient(IGitHubClient client)
{
Ensure.ArgumentNotNull(client, "client");
_client = client.Deployment.Status;
_connection = client.Connection;
}
/// <summary>
/// Gets all the statuses for the given deployment. Any user with pull access to a repository can
/// view deployments.
/// </summary>
/// <remarks>
/// http://developer.github.com/v3/repos/deployments/#list-deployment-statuses
/// </remarks>
/// <param name="owner">The owner of the repository.</param>
/// <param name="name">The name of the repository.</param>
/// <param name="deploymentId">The id of the deployment.</param>
/// <returns>All deployment statuses for the given deployment.</returns>
public IObservable<DeploymentStatus> GetAll(string owner, string name, int deploymentId)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
return _connection.GetAndFlattenAllPages<DeploymentStatus>(
ApiUrls.DeploymentStatuses(owner, name, deploymentId),
null, acceptsHeader);
}
/// <summary>
/// Creates a new status for the given deployment. Users with push access can create deployment
/// statuses for a given deployment.
/// </summary>
/// <remarks>
/// http://developer.github.com/v3/repos/deployments/#create-a-deployment-status
/// </remarks>
/// <param name="owner">The owner of the repository.</param>
/// <param name="name">The name of the repository.</param>
/// <param name="deploymentId">The id of the deployment.</param>
/// <param name="newDeploymentStatus">The new deployment status to create.</param>
/// <returns></returns>
public IObservable<DeploymentStatus> Create(string owner, string name, int deploymentId, NewDeploymentStatus newDeploymentStatus)
{
return _client.Create(owner, name, deploymentId, newDeploymentStatus).ToObservable();
}
}
}

View File

@@ -0,0 +1,55 @@
using Octokit.Reactive.Internal;
using System;
using System.Reactive.Threading.Tasks;
namespace Octokit.Reactive.Clients
{
public class ObservableDeploymentsClient : IObservableDeploymentsClient
{
readonly IDeploymentsClient _client;
readonly IConnection _connection;
public ObservableDeploymentsClient(IGitHubClient client)
{
Ensure.ArgumentNotNull(client, "client");
_client = client.Deployment;
_connection = client.Connection;
}
/// <summary>
/// Gets all the deployments for the specified repository. Any user with pull access
/// to a repository can view deployments.
/// </summary>
/// <remarks>
/// http://developer.github.com/v3/repos/deployments/#list-deployments
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns>All the <see cref="Deployment"/>s for the specified repository.</returns>
public IObservable<Deployment> GetAll(string owner, string name)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
return _connection.GetAndFlattenAllPages<Deployment>(
ApiUrls.Deployments(owner, name), null, "application/vnd.github.cannonball-preview+json");
}
/// <summary>
/// Creates a new deployment for the specified repository.
/// Users with push access can create a deployment for a given ref.
/// </summary>
/// <remarks>
/// http://developer.github.com/v3/repos/deployments/#create-a-deployment
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="newDeployment">A <see cref="NewDeployment"/> instance describing the new deployment to create</param>
/// <returns>The created <see cref="Deployment"></returns>
public IObservable<Deployment> Create(string owner, string name, NewDeployment newDeployment)
{
return _client.Create(owner, name, newDeployment).ToObservable();
}
}
}

View File

@@ -11,7 +11,7 @@
Reference = new ObservableReferencesClient(client); Reference = new ObservableReferencesClient(client);
} }
public IObservableBlobClient Blob { get; set; } public IObservableBlobsClient Blob { get; set; }
public IObservableTagsClient Tag { get; set; } public IObservableTagsClient Tag { get; set; }
public IObservableTreesClient Tree { get; set; } public IObservableTreesClient Tree { get; set; }
public IObservableCommitsClient Commit { get; set; } public IObservableCommitsClient Commit { get; set; }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Reactive;
using System.Reactive.Threading.Tasks; using System.Reactive.Threading.Tasks;
using Octokit.Reactive.Internal; using Octokit.Reactive.Internal;
@@ -109,5 +110,21 @@ namespace Octokit.Reactive
return _client.Update(owner, name, number, commentUpdate).ToObservable(); return _client.Update(owner, name, number, commentUpdate).ToObservable();
} }
/// <summary>
/// Deletes the specified Issue Comment
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#delete-a-comment</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="number">The comment number</param>
/// <returns></returns>
public IObservable<Unit> Delete(string owner, string name, int number)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
return _client.Delete(owner, name, number).ToObservable();
}
} }
} }

View File

@@ -10,8 +10,10 @@ namespace Octokit.Reactive
readonly IConnection _connection; readonly IConnection _connection;
public IObservableAssigneesClient Assignee { get; private set; } public IObservableAssigneesClient Assignee { get; private set; }
public IObservableIssueCommentsClient Comment { get; private set; }
public IObservableIssuesEventsClient Events { get; private set; }
public IObservableIssuesLabelsClient Labels { get; private set; }
public IObservableMilestonesClient Milestone { get; private set; } public IObservableMilestonesClient Milestone { get; private set; }
public IObservableIssueCommentsClient Comments { get; private set; }
public ObservableIssuesClient(IGitHubClient client) public ObservableIssuesClient(IGitHubClient client)
{ {
@@ -20,8 +22,10 @@ namespace Octokit.Reactive
_client = client.Issue; _client = client.Issue;
_connection = client.Connection; _connection = client.Connection;
Assignee = new ObservableAssigneesClient(client); Assignee = new ObservableAssigneesClient(client);
Events = new ObservableIssuesEventsClient(client);
Labels = new ObservableIssuesLabelsClient(client);
Milestone = new ObservableMilestonesClient(client); Milestone = new ObservableMilestonesClient(client);
Comments = new ObservableIssueCommentsClient(client); Comment = new ObservableIssueCommentsClient(client);
} }
/// <summary> /// <summary>

View File

@@ -0,0 +1,195 @@
using System;
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;
using Octokit.Reactive.Internal;
namespace Octokit.Reactive
{
public class ObservableIssuesLabelsClient : IObservableIssuesLabelsClient
{
readonly IIssuesLabelsClient _client;
readonly IConnection _connection;
public ObservableIssuesLabelsClient(IGitHubClient client)
{
Ensure.ArgumentNotNull(client, "client");
_connection = client.Connection;
_client = client.Issue.Labels;
}
/// <summary>
/// Gets all labels for the issue.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#list-labels-on-an-issue">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="number">The number of the issue</param>
/// <returns>The list of labels</returns>
public IObservable<Label> GetForIssue(string owner, string repo, int number)
{
return _connection.GetAndFlattenAllPages<Label>(ApiUrls.IssueLabels(owner, repo, number));
}
/// <summary>
/// Gets all labels for the repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <returns>The list of labels</returns>
public IObservable<Label> GetForRepository(string owner, string repo)
{
return _connection.GetAndFlattenAllPages<Label>(ApiUrls.Labels(owner, repo));
}
/// <summary>
/// Gets a single Label by name.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#get-a-single-label">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="name">The name of the label</param>
/// <returns>The label</returns>
public IObservable<Label> Get(string owner, string repo, string name)
{
return _client.Get(owner, repo, name).ToObservable();
}
/// <summary>
/// Deletes a label.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#delete-a-label">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="name">The name of the label</param>
/// <returns></returns>
public IObservable<Unit> Delete(string owner, string repo, string name)
{
return _client.Delete(owner, repo, name).ToObservable();
}
/// <summary>
/// Creates a label.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#create-a-label">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="newLabel">The data for the label to be created</param>
/// <returns>The created label</returns>
public IObservable<Label> Create(string owner, string repo, NewLabel newLabel)
{
return _client.Create(owner, repo, newLabel).ToObservable();
}
/// <summary>
/// Updates a label.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#update-a-label">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="name">The name of the label</param>
/// <param name="labelUpdate">The data for the label to be updated</param>
/// <returns>The updated label</returns>'
public IObservable<Label> Update(string owner, string repo, string name, LabelUpdate labelUpdate)
{
return _client.Update(owner, repo, name, labelUpdate).ToObservable();
}
/// <summary>
/// Adds a label to an issue
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#add-labels-to-an-issue">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="number">The number of the issue</param>
/// <param name="labels">The names of the labels to add</param>
/// <returns></returns>
public IObservable<Label> AddToIssue(string owner, string repo, int number, string[] labels)
{
return _client.AddToIssue(owner, repo, number, labels)
.ToObservable()
.SelectMany(x => x); // HACK: POST is not compatible with GetAndFlattenPages
}
/// <summary>
/// Removes a label from an issue
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="number">The number of the issue</param>
/// <param name="label">The name of the label to remove</param>
/// <returns></returns>
public IObservable<Unit> RemoveFromIssue(string owner, string repo, int number, string label)
{
return _client.RemoveFromIssue(owner, repo, number, label).ToObservable();
}
/// <summary>
/// Replaces all labels on the specified issues with the provided labels
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="number">The number of the issue</param>
/// <param name="labels">The names of the labels to set</param>
/// <returns></returns>
public IObservable<Label> ReplaceAllForIssue(string owner, string repo, int number, string[] labels)
{
return _client.ReplaceAllForIssue(owner, repo, number, labels)
.ToObservable()
.SelectMany(x => x); // HACK: PUT is not compatible with GetAndFlattenPages
}
/// <summary>
/// Removes all labels from an issue
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#remove-all-labels-from-an-issue">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="number">The number of the issue</param>
/// <returns></returns>
public IObservable<Unit> RemoveAllFromIssue(string owner, string repo, int number)
{
return _client.RemoveAllFromIssue(owner, repo, number).ToObservable();
}
/// <summary>
/// Gets labels for every issue in a milestone
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repo">The name of the repository</param>
/// <param name="number">The number of the milestone</param>
/// <returns></returns>
public IObservable<Label> GetForMilestone(string owner, string repo, int number)
{
return _connection.GetAndFlattenAllPages<Label>(ApiUrls.MilestoneLabels(owner, repo, number));
}
}
}

View File

@@ -18,7 +18,7 @@ namespace Octokit.Reactive
Ensure.ArgumentNotNull(client, "client"); Ensure.ArgumentNotNull(client, "client");
Member = new ObservableOrganizationMembersClient(client); Member = new ObservableOrganizationMembersClient(client);
Teams = new ObservableOrganizationTeamsClient(client); Team = new ObservableTeamsClient(client);
_client = client.Organization; _client = client.Organization;
_connection = client.Connection; _connection = client.Connection;
@@ -32,7 +32,7 @@ namespace Octokit.Reactive
/// <summary> /// <summary>
/// Returns a client to manage teams for an organization. /// Returns a client to manage teams for an organization.
/// </summary> /// </summary>
public IObservableOrganizationTeamsClient Teams { get; private set; } public IObservableTeamsClient Team { get; private set; }
/// <summary> /// <summary>
/// Returns the specified organization. /// Returns the specified organization.

View File

@@ -64,7 +64,7 @@ namespace Octokit.Reactive
/// <param name="name">The name of the repository</param> /// <param name="name">The name of the repository</param>
/// <param name="subNamespace">The sub-namespace to get references for</param> /// <param name="subNamespace">The sub-namespace to get references for</param>
/// <returns></returns> /// <returns></returns>
public IObservable<Reference> GetAll(string owner, string name, string subNamespace) public IObservable<Reference> GetAllForSubNamespace(string owner, string name, string subNamespace)
{ {
Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNullOrEmptyString(name, "name");

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Reactive;
using System.Reactive.Threading.Tasks; using System.Reactive.Threading.Tasks;
using Octokit.Reactive.Internal; using Octokit.Reactive.Internal;
@@ -17,19 +18,203 @@ namespace Octokit.Reactive
_connection = client.Connection; _connection = client.Connection;
} }
/// <summary>
/// Gets all <see cref="Release"/>s for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#list-releases-for-a-repository">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>The list of <see cref="Release"/>s for the specified repository.</returns>
public IObservable<Release> GetAll(string owner, string name) public IObservable<Release> GetAll(string owner, string name)
{ {
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
return _connection.GetAndFlattenAllPages<Release>(ApiUrls.Releases(owner, name)); return _connection.GetAndFlattenAllPages<Release>(ApiUrls.Releases(owner, name));
} }
/// <summary>
/// Gets a single <see cref="Release"/> for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#get-a-single-release">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="number">The id of the release</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>The <see cref="Release"/> specified by the id</returns>
public IObservable<Release> Get(string owner, string name, int number)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNull(number, "number");
return _client.Get(owner, name, number).ToObservable();
}
/// <summary>
/// Creates a new <see cref="Release"/> for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#create-a-release">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="data">A description of the release to create</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>The created <see cref="Release"/>.</returns>
public IObservable<Release> CreateRelease(string owner, string name, ReleaseUpdate data) public IObservable<Release> CreateRelease(string owner, string name, ReleaseUpdate data)
{ {
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNull(data, "data");
return _client.CreateRelease(owner, name, data).ToObservable(); return _client.CreateRelease(owner, name, data).ToObservable();
} }
/// <summary>
/// Edits an existing <see cref="Release"/> for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#edit-a-release">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="data">A description of the release to edit</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>The updated <see cref="Release"/>.</returns>
public IObservable<Release> EditRelease(string owner, string name, ReleaseUpdate data)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNull(data, "data");
return _client.EditRelease(owner, name, data).ToObservable();
}
/// <summary>
/// Deletes an existing <see cref="Release"/> for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#delete-a-release">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="number">The id of the release to delete</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns></returns>
public IObservable<Unit> DeleteRelease(string owner, string name, int number)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNull(number, "number");
return _client.DeleteRelease(owner, name, number).ToObservable();
}
/// <summary>
/// Gets all <see cref="ReleaseAsset"/> for the specified release of the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#list-assets-for-a-release">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="number">The id of the <see cref="Release"/>.</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>The list of <see cref="ReleaseAsset"/> for the specified release of the specified repository.</returns>
public IObservable<ReleaseAsset> GetAssets(string owner, string name, int number)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNull(number, "number");
return _connection.GetAndFlattenAllPages<ReleaseAsset>(ApiUrls.ReleaseAssets(owner, name, number));
}
/// <summary>
/// Uploads a <see cref="ReleaseAsset"/> for the specified release.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#upload-a-release-asset">API documentation</a> for more information.
/// </remarks>
/// <param name="release">The <see cref="Release"/> to attach the uploaded asset to</param>
/// <param name="data">Description of the asset with its data</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>The created <see cref="ReleaseAsset"/>.</returns>
public IObservable<ReleaseAsset> GetAsset(string owner, string name, int releaseId, int assetId)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNull(releaseId, "releaseId");
Ensure.ArgumentNotNull(assetId, "assetId");
return _client.GetAsset(owner, name, releaseId, assetId).ToObservable();
}
/// <summary>
/// Gets the specified <see cref="ReleaseAsset"/> for the specified release of the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#get-a-single-release-asset">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="releaseId">The id of the <see cref="Release"/></param>
/// <param name="assetId">The id of the <see cref="ReleaseAsset"/></param>
/// <returns>The <see cref="ReleaseAsset"/> specified by the asset id.</returns>
public IObservable<ReleaseAsset> UploadAsset(Release release, ReleaseAssetUpload data) public IObservable<ReleaseAsset> UploadAsset(Release release, ReleaseAssetUpload data)
{ {
Ensure.ArgumentNotNull(release, "release");
Ensure.ArgumentNotNull(data, "data");
return _client.UploadAsset(release, data).ToObservable(); return _client.UploadAsset(release, data).ToObservable();
} }
/// <summary>
/// Edits the <see cref="ReleaseAsset"/> for the specified release of the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#edit-a-release-asset">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="releaseId">The id of the <see cref="Release"/></param>
/// <param name="assetId">The id of the <see cref="ReleaseAsset"/></param>
/// <param name="data">Description of the asset with its amended data</param>
/// <returns>The edited <see cref="ReleaseAsset"/>.</returns>
public IObservable<ReleaseAsset> EditAsset(string owner, string name, int releaseId, int assetId, ReleaseAssetUpdate data)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNull(releaseId, "releaseId");
Ensure.ArgumentNotNull(assetId, "assetId");
Ensure.ArgumentNotNull(data, "data");
return _client.EditAsset(owner, name, releaseId, assetId, data).ToObservable();
}
/// <summary>
/// Deletes the specified <see cref="ReleaseAsset"/> from the specified repository
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/releases/#delete-a-release-asset">API documentation</a> for more information.
/// </remarks>
/// <param name="owner">The repository's owner</param>
/// <param name="name">The repository's name</param>
/// <param name="number">The id of the <see cref="ReleaseAsset"/>.</param>
/// <returns></returns>
public IObservable<Unit> DeleteAsset(string owner, string name, int number)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
Ensure.ArgumentNotNull(number, "number");
return _client.DeleteAsset(owner, name, number).ToObservable();
}
} }
} }

View File

@@ -23,13 +23,13 @@ namespace Octokit.Reactive
/// Gets all the available collaborators on this repo. /// Gets all the available collaborators on this repo.
/// </summary> /// </summary>
/// <param name="owner">The owner of the repository</param> /// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param> /// <param name="repo">The name of the repository</param>
/// <returns></returns> /// <returns></returns>
public IObservable<User> GetAll(string owner, string name) public IObservable<User> GetAll(string owner, string repo)
{ {
Ensure.ArgumentNotNull(owner, "owner"); Ensure.ArgumentNotNull(owner, "owner");
Ensure.ArgumentNotNull(name, "name"); Ensure.ArgumentNotNull(repo, "name");
var endpoint = ApiUrls.RepoCollaborators(owner, name); var endpoint = ApiUrls.RepoCollaborators(owner, repo);
return _connection.GetAndFlattenAllPages<User>(endpoint); return _connection.GetAndFlattenAllPages<User>(endpoint);
} }
@@ -37,36 +37,36 @@ namespace Octokit.Reactive
/// Checks to see if a user is an assignee for a repository. /// Checks to see if a user is an assignee for a repository.
/// </summary> /// </summary>
/// <param name="owner">The owner of the repository</param> /// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param> /// <param name="repo">The name of the repository</param>
/// <param name="user">Username of the prospective collaborator</param> /// <param name="user">Username of the prospective collaborator</param>
/// <returns></returns> /// <returns></returns>
public IObservable<bool> IsCollaborator(string owner, string name, string user) public IObservable<bool> IsCollaborator(string owner, string repo, string user)
{ {
return _client.IsCollaborator(owner, name, user).ToObservable(); return _client.IsCollaborator(owner, repo, user).ToObservable();
} }
/// <summary> /// <summary>
/// Adds a user as a collaborator to a repository. /// Adds a user as a collaborator to a repository.
/// </summary> /// </summary>
/// <param name="owner">The owner of the repository</param> /// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param> /// <param name="repo">The name of the repository</param>
/// <param name="user">Username of the prospective collaborator</param> /// <param name="user">Username of the prospective collaborator</param>
/// <returns></returns> /// <returns></returns>
public IObservable<Unit> Add(string owner, string name, string user) public IObservable<Unit> Add(string owner, string repo, string user)
{ {
return _client.Add(owner, name, user).ToObservable(); return _client.Add(owner, repo, user).ToObservable();
} }
/// <summary> /// <summary>
/// Removes a user as a collaborator for a repository. /// Removes a user as a collaborator for a repository.
/// </summary> /// </summary>
/// <param name="owner">The owner of the repository</param> /// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param> /// <param name="repo">The name of the repository</param>
/// <param name="user">Username of the prospective collaborator</param> /// <param name="user">Username of the prospective collaborator</param>
/// <returns></returns> /// <returns></returns>
public IObservable<Unit> Delete(string owner, string name, string user) public IObservable<Unit> Delete(string owner, string repo, string user)
{ {
return _client.Delete(owner, name, user).ToObservable(); return _client.Delete(owner, repo, user).ToObservable();
} }
} }
} }

View File

@@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks; using System.Reactive.Threading.Tasks;
using Octokit.Reactive.Internal; using Octokit.Reactive.Internal;
@@ -17,6 +19,7 @@ namespace Octokit.Reactive
_client = client.Repository; _client = client.Repository;
_connection = client.Connection; _connection = client.Connection;
CommitStatus = new ObservableCommitStatusClient(client); CommitStatus = new ObservableCommitStatusClient(client);
RepoCollaborators = new ObservableRepoCollaboratorsClient(client);
} }
/// <summary> /// <summary>
@@ -156,5 +159,151 @@ namespace Octokit.Reactive
/// that announced this feature. /// that announced this feature.
/// </remarks> /// </remarks>
public IObservableCommitStatusClient CommitStatus { get; private set; } public IObservableCommitStatusClient CommitStatus { get; private set; }
/// <summary>
/// Gets all the branches for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#list-branches">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <exception cref="ApiException">Thrown when a general API error occurs.</exception>
/// <returns>All <see cref="T:Octokit.Branch"/>es of the repository</returns>
public IObservable<Branch> GetAllBranches(string owner, string name)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
var endpoint = ApiUrls.RepoBranches(owner, name);
return _connection.GetAndFlattenAllPages<Branch>(endpoint);
}
/// <summary>
/// Gets all contributors for the specified repository. Does not include anonymous contributors.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#list-contributors">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns>All contributors of the repository.</returns>
public IObservable<User> GetAllContributors(string owner, string name)
{
return GetAllContributors(owner, name, false);
}
/// <summary>
/// Gets all contributors for the specified repository. With the option to include anonymous contributors.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#list-contributors">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="includeAnonymous">True if anonymous contributors should be included in result; Otherwise false</param>
/// <returns>All contributors of the repository.</returns>
public IObservable<User> GetAllContributors(string owner, string name, bool includeAnonymous)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
var endpoint = ApiUrls.RepositoryContributors(owner, name);
var parameters = new Dictionary<string, string>();
if (includeAnonymous)
parameters.Add("anon", "1");
return _connection.GetAndFlattenAllPages<User>(endpoint, parameters);
}
/// <summary>
/// Gets all languages for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#list-languages">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns>All languages used in the repository and the number of bytes of each language.</returns>
public IObservable<RepositoryLanguage> GetAllLanguages(string owner, string name)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
var endpoint = ApiUrls.RepositoryLanguages(owner, name);
return _connection
.GetAndFlattenAllPages<Tuple<string, long>>(endpoint)
.Select(t => new RepositoryLanguage(t.Item1, t.Item2));
}
/// <summary>
/// Gets all teams for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#list-teams">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns>All <see cref="T:Octokit.Team"/>s associated with the repository</returns>
public IObservable<Team> GetAllTeams(string owner, string name)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
var endpoint = ApiUrls.RepositoryTeams(owner, name);
return _connection.GetAndFlattenAllPages<Team>(endpoint);
}
/// <summary>
/// Gets all tags for the specified repository.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#list-tags">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <returns>All of the repositorys tags.</returns>
public IObservable<RepositoryTag> GetAllTags(string owner, string name)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
var endpoint = ApiUrls.RepositoryTags(owner, name);
return _connection.GetAndFlattenAllPages<RepositoryTag>(endpoint);
}
/// <summary>
/// Gets the specified branch.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/#get-branch">API documentation</a> for more details
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="repositoryName">The name of the repository</param>
/// <param name="branchName">The name of the branch</param>
/// <returns>The specified <see cref="T:Octokit.Branch"/></returns>
public IObservable<Branch> GetBranch(string owner, string repositoryName, string branchName)
{
return _client.GetBranch(owner, repositoryName, branchName).ToObservable();
}
/// <summary>
/// Updates the specified repository with the values given in <paramref name="update"/>
/// </summary>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="update">New values to update the repository with</param>
/// <returns>The updated <see cref="T:Octokit.Repository"/></returns>
public IObservable<Repository> Edit(string owner, string name, RepositoryUpdate update)
{
return _client.Edit(owner, name, update).ToObservable();
}
/// A client for GitHub's Repo Collaborators.
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/collaborators/">Collaborators API documentation</a> for more details
/// </remarks>
public IObservableRepoCollaboratorsClient RepoCollaborators { get; private set; }
} }
} }

View File

@@ -20,48 +20,48 @@ namespace Octokit.Reactive
/// search repos /// search repos
/// http://developer.github.com/v3/search/#search-repositories /// http://developer.github.com/v3/search/#search-repositories
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="search"></param>
/// <returns>List of repositories</returns> /// <returns>List of repositories</returns>
public IObservable<Repository> SearchRepo(SearchRepositoriesRequest request) public IObservable<Repository> SearchRepo(SearchRepositoriesRequest search)
{ {
Ensure.ArgumentNotNull(request, "request"); Ensure.ArgumentNotNull(search, "search");
return _connection.GetAndFlattenAllPages<Repository>(ApiUrls.SearchRepositories(), request.Parameters); return _connection.GetAndFlattenAllPages<Repository>(ApiUrls.SearchRepositories(), search.Parameters);
} }
/// <summary> /// <summary>
/// search users /// search users
/// http://developer.github.com/v3/search/#search-users /// http://developer.github.com/v3/search/#search-users
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="search"></param>
/// <returns>List of users</returns> /// <returns>List of users</returns>
public IObservable<User> SearchUsers(SearchUsersRequest request) public IObservable<User> SearchUsers(SearchUsersRequest search)
{ {
Ensure.ArgumentNotNull(request, "request"); Ensure.ArgumentNotNull(search, "search");
return _connection.GetAndFlattenAllPages<User>(ApiUrls.SearchUsers(), request.ToParametersDictionary()); return _connection.GetAndFlattenAllPages<User>(ApiUrls.SearchUsers(), search.Parameters);
} }
/// <summary> /// <summary>
/// search issues /// search issues
/// http://developer.github.com/v3/search/#search-issues /// http://developer.github.com/v3/search/#search-issues
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="search"></param>
/// <returns>List of issues</returns> /// <returns>List of issues</returns>
public IObservable<Issue> SearchIssues(SearchIssuesRequest request) public IObservable<Issue> SearchIssues(SearchIssuesRequest search)
{ {
Ensure.ArgumentNotNull(request, "request"); Ensure.ArgumentNotNull(search, "search");
return _connection.GetAndFlattenAllPages<Issue>(ApiUrls.SearchIssues(), request.Parameters); return _connection.GetAndFlattenAllPages<Issue>(ApiUrls.SearchIssues(), search.Parameters);
} }
/// <summary> /// <summary>
/// search code /// search code
/// http://developer.github.com/v3/search/#search-code /// http://developer.github.com/v3/search/#search-code
/// </summary> /// </summary>
/// <param name="request"></param> /// <param name="search"></param>
/// <returns>List of files</returns> /// <returns>List of files</returns>
public IObservable<SearchCode> SearchCode(SearchCodeRequest request) public IObservable<SearchCode> SearchCode(SearchCodeRequest search)
{ {
Ensure.ArgumentNotNull(request, "request"); Ensure.ArgumentNotNull(search, "search");
return _connection.GetAndFlattenAllPages<SearchCode>(ApiUrls.SearchCode(), request.Parameters); return _connection.GetAndFlattenAllPages<SearchCode>(ApiUrls.SearchCode(), search.Parameters);
} }
} }
} }

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Reactive.Threading.Tasks;
namespace Octokit.Reactive
{
public class ObservableStatisticsClient : IObservableStatisticsClient
{
readonly IGitHubClient _client;
public ObservableStatisticsClient(IGitHubClient client)
{
Ensure.ArgumentNotNull(client, "client");
_client = client;
}
public IObservable<IEnumerable<Contributor>> GetContributors(string owner, string repositoryName)
{
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(repositoryName, "repositoryName");
return _client.Statistics.GetContributors(owner, repositoryName).ToObservable();
}
}
}

View File

@@ -5,7 +5,7 @@ using Octokit.Reactive.Internal;
namespace Octokit.Reactive namespace Octokit.Reactive
{ {
public class ObservableOrganizationTeamsClient : IObservableOrganizationTeamsClient public class ObservableTeamsClient : IObservableTeamsClient
{ {
readonly IConnection _connection; readonly IConnection _connection;
readonly ITeamsClient _client; readonly ITeamsClient _client;
@@ -14,7 +14,7 @@ namespace Octokit.Reactive
/// Initializes a new Organization Teams API client. /// Initializes a new Organization Teams API client.
/// </summary> /// </summary>
/// <param name="client">An <see cref="IGitHubClient" /> used to make the requests</param> /// <param name="client">An <see cref="IGitHubClient" /> used to make the requests</param>
public ObservableOrganizationTeamsClient(IGitHubClient client) public ObservableTeamsClient(IGitHubClient client)
{ {
Ensure.ArgumentNotNull(client, "client"); Ensure.ArgumentNotNull(client, "client");
_connection = client.Connection; _connection = client.Connection;

View File

@@ -0,0 +1,31 @@
using Octokit.Reactive.Internal;
using System;
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;
namespace Octokit.Reactive
{
public class ObservableUserEmailsClient : IObservableUserEmailsClient
{
readonly IUserEmailsClient _client;
readonly IConnection _connection;
public ObservableUserEmailsClient(IGitHubClient client)
{
Ensure.ArgumentNotNull(client, "client");
_client = client.User.Email;
_connection = client.Connection;
}
public IObservable<EmailAddress> GetAll()
{
return _connection.GetAndFlattenAllPages<EmailAddress>(ApiUrls.Emails());
}
public IObservable<string> Add(params string[] emailAddresses)
{
return _client.Add(emailAddresses).ToObservable().SelectMany(a => a);
}
}
}

View File

@@ -1,20 +1,19 @@
using System; using System;
using System.Reactive.Threading.Tasks; using System.Reactive.Threading.Tasks;
using Octokit.Reactive.Internal;
namespace Octokit.Reactive namespace Octokit.Reactive
{ {
public class ObservableUsersClient : IObservableUsersClient public class ObservableUsersClient : IObservableUsersClient
{ {
readonly IUsersClient _client; readonly IUsersClient _client;
readonly IConnection _connection;
public ObservableUsersClient(IGitHubClient client) public ObservableUsersClient(IGitHubClient client)
{ {
Ensure.ArgumentNotNull(client, "client"); Ensure.ArgumentNotNull(client, "client");
_client = client.User; _client = client.User;
_connection = client.Connection;
Followers = new ObservableFollowersClient(client);
} }
/// <summary> /// <summary>
@@ -52,12 +51,11 @@ namespace Octokit.Reactive
} }
/// <summary> /// <summary>
/// Returns emails for the current user. /// A client for GitHub's User Followers API
/// </summary> /// </summary>
/// <returns></returns> /// <remarks>
public IObservable<EmailAddress> GetEmails() /// See the <a href="http://developer.github.com/v3/users/followers/">Followers API documentation</a> for more information.
{ ///</remarks>
return _connection.GetAndFlattenAllPages<EmailAddress>(ApiUrls.Emails()); public IObservableFollowersClient Followers { get; private set; }
}
} }
} }

View File

@@ -63,7 +63,7 @@ namespace Octokit.Reactive
/// <param name="name">The name of the repository</param> /// <param name="name">The name of the repository</param>
/// <exception cref="AuthorizationException">Thrown if the client is not authenticated</exception> /// <exception cref="AuthorizationException">Thrown if the client is not authenticated</exception>
/// <returns>A <c>bool</c> representing the success of the operation</returns> /// <returns>A <c>bool</c> representing the success of the operation</returns>
public IObservable<bool> CheckStarred(string owner, string name) public IObservable<bool> CheckWatched(string owner, string name)
{ {
Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name"); Ensure.ArgumentNotNullOrEmptyString(name, "name");

View File

@@ -6,14 +6,16 @@
IObservableAuthorizationsClient Authorization { get; } IObservableAuthorizationsClient Authorization { get; }
IObservableActivitiesClient Activity { get; } IObservableActivitiesClient Activity { get; }
IObservableBlobClient Blob { get; } IObservableIssuesClient Issue { get; }
IObservableMiscellaneousClient Miscellaneous { get; } IObservableMiscellaneousClient Miscellaneous { get; }
IObservableOrganizationsClient Organization { get; } IObservableOrganizationsClient Organization { get; }
IObservableRepositoriesClient Repository { get; } IObservableRepositoriesClient Repository { get; }
IObservableGistsClient Gist { get; }
IObservableReleasesClient Release { get; }
IObservableSshKeysClient SshKey { get; } IObservableSshKeysClient SshKey { get; }
IObservableUsersClient User { get; } IObservableUsersClient User { get; }
IObservableNotificationsClient Notification { get; }
IObservableGitDatabaseClient GitDatabase { get; } IObservableGitDatabaseClient GitDatabase { get; }
IObservableTreesClient Tree { get; } IObservableSearchClient Search { get; }
IObservableGistsClient Gist { get; }
} }
} }

View File

@@ -34,7 +34,7 @@ namespace Octokit.Reactive
_gitHubClient = gitHubClient; _gitHubClient = gitHubClient;
Authorization = new ObservableAuthorizationsClient(gitHubClient); Authorization = new ObservableAuthorizationsClient(gitHubClient);
Activity = new ObservableActivitiesClient(gitHubClient); Activity = new ObservableActivitiesClient(gitHubClient);
Blob = new ObservableBlobClient(gitHubClient); Issue = new ObservableIssuesClient(gitHubClient);
Miscellaneous = new ObservableMiscellaneousClient(gitHubClient.Miscellaneous); Miscellaneous = new ObservableMiscellaneousClient(gitHubClient.Miscellaneous);
Notification = new ObservableNotificationsClient(gitHubClient); Notification = new ObservableNotificationsClient(gitHubClient);
Organization = new ObservableOrganizationsClient(gitHubClient); Organization = new ObservableOrganizationsClient(gitHubClient);
@@ -43,8 +43,8 @@ namespace Octokit.Reactive
User = new ObservableUsersClient(gitHubClient); User = new ObservableUsersClient(gitHubClient);
Release = new ObservableReleasesClient(gitHubClient); Release = new ObservableReleasesClient(gitHubClient);
GitDatabase = new ObservableGitDatabaseClient(gitHubClient); GitDatabase = new ObservableGitDatabaseClient(gitHubClient);
Tree = new ObservableTreesClient(gitHubClient);
Gist = new ObservableGistsClient(gitHubClient); Gist = new ObservableGistsClient(gitHubClient);
Search = new ObservableSearchClient(gitHubClient);
} }
public IConnection Connection public IConnection Connection
@@ -54,16 +54,16 @@ namespace Octokit.Reactive
public IObservableAuthorizationsClient Authorization { get; private set; } public IObservableAuthorizationsClient Authorization { get; private set; }
public IObservableActivitiesClient Activity { get; private set; } public IObservableActivitiesClient Activity { get; private set; }
public IObservableBlobClient Blob { get; private set; } public IObservableIssuesClient Issue { 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 IObservableGistsClient Gist { get; private set; }
public IObservableReleasesClient Release { get; private set; } public IObservableReleasesClient Release { get; private set; }
public IObservableSshKeysClient SshKey { get; private set; } public IObservableSshKeysClient SshKey { get; private set; }
public IObservableUsersClient User { get; private set; } public IObservableUsersClient User { get; private set; }
public IObservableNotificationsClient Notification { get; private set; }
public IObservableGitDatabaseClient GitDatabase { get; private set; } public IObservableGitDatabaseClient GitDatabase { get; private set; }
public IObservableTreesClient Tree { get; private set; } public IObservableSearchClient Search { get; private set; }
public IObservableGistsClient Gist { get; private set; }
} }
} }

View File

@@ -118,12 +118,25 @@
<Compile Include="Clients\ObservableGistsClient.cs" /> <Compile Include="Clients\ObservableGistsClient.cs" />
<Compile Include="Clients\IObservableSearchClient.cs" /> <Compile Include="Clients\IObservableSearchClient.cs" />
<Compile Include="Clients\ObservableSearchClient.cs" /> <Compile Include="Clients\ObservableSearchClient.cs" />
<Compile Include="Clients\ObservableDeploymentsClient.cs" />
<Compile Include="Clients\IObservableDeploymentsClient.cs" />
<Compile Include="Clients\IObservableDeploymentStatusClient.cs" />
<Compile Include="Clients\ObservableDeploymentStatusClient.cs" />
<Compile Include="Clients\IObservableWatchedClient.cs" /> <Compile Include="Clients\IObservableWatchedClient.cs" />
<Compile Include="Clients\ObservableWatchedClient.cs" /> <Compile Include="Clients\ObservableWatchedClient.cs" />
<Compile Include="Clients\IObservableFollowersClient.cs" /> <Compile Include="Clients\IObservableFollowersClient.cs" />
<Compile Include="Clients\ObservableFollowersClient.cs" /> <Compile Include="Clients\ObservableFollowersClient.cs" />
<Compile Include="Clients\IObservablePullRequestsClient.cs" /> <Compile Include="Clients\IObservablePullRequestsClient.cs" />
<Compile Include="Clients\ObservablePullRequestsClient.cs" /> <Compile Include="Clients\ObservablePullRequestsClient.cs" />
<Compile Include="Clients\IObservableUserEmailsClient.cs" />
<Compile Include="Clients\ObservableUserEmailsClient.cs" />
<Compile Include="Clients\IObservableStatisticsClient.cs" />
<Compile Include="Clients\ObservableStatisticsClient.cs" />
<Compile Include="Clients\IObservableBlobsClient.cs" />
<Compile Include="Clients\IObservableIssuesLabelsClient.cs" />
<Compile Include="Clients\IObservableTeamsClient.cs" />
<Compile Include="Clients\ObservableTeamsClient.cs" />
<Compile Include="Clients\ObservableIssuesLabelsClient.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup> <ItemGroup>

View File

@@ -127,12 +127,25 @@
<Compile Include="Clients\ObservableGistsClient.cs" /> <Compile Include="Clients\ObservableGistsClient.cs" />
<Compile Include="Clients\IObservableSearchClient.cs" /> <Compile Include="Clients\IObservableSearchClient.cs" />
<Compile Include="Clients\ObservableSearchClient.cs" /> <Compile Include="Clients\ObservableSearchClient.cs" />
<Compile Include="Clients\ObservableDeploymentsClient.cs" />
<Compile Include="Clients\IObservableDeploymentsClient.cs" />
<Compile Include="Clients\IObservableDeploymentStatusClient.cs" />
<Compile Include="Clients\ObservableDeploymentStatusClient.cs" />
<Compile Include="Clients\IObservableWatchedClient.cs" /> <Compile Include="Clients\IObservableWatchedClient.cs" />
<Compile Include="Clients\ObservableWatchedClient.cs" /> <Compile Include="Clients\ObservableWatchedClient.cs" />
<Compile Include="Clients\IObservableFollowersClient.cs" /> <Compile Include="Clients\IObservableFollowersClient.cs" />
<Compile Include="Clients\ObservableFollowersClient.cs" /> <Compile Include="Clients\ObservableFollowersClient.cs" />
<Compile Include="Clients\IObservablePullRequestsClient.cs" /> <Compile Include="Clients\IObservablePullRequestsClient.cs" />
<Compile Include="Clients\ObservablePullRequestsClient.cs" /> <Compile Include="Clients\ObservablePullRequestsClient.cs" />
<Compile Include="Clients\IObservableUserEmailsClient.cs" />
<Compile Include="Clients\ObservableUserEmailsClient.cs" />
<Compile Include="Clients\IObservableStatisticsClient.cs" />
<Compile Include="Clients\ObservableStatisticsClient.cs" />
<Compile Include="Clients\IObservableBlobsClient.cs" />
<Compile Include="Clients\IObservableIssuesLabelsClient.cs" />
<Compile Include="Clients\IObservableTeamsClient.cs" />
<Compile Include="Clients\ObservableTeamsClient.cs" />
<Compile Include="Clients\ObservableIssuesLabelsClient.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />
<ItemGroup> <ItemGroup>

View File

@@ -122,12 +122,25 @@
<Compile Include="Clients\ObservableGistsClient.cs" /> <Compile Include="Clients\ObservableGistsClient.cs" />
<Compile Include="Clients\IObservableSearchClient.cs" /> <Compile Include="Clients\IObservableSearchClient.cs" />
<Compile Include="Clients\ObservableSearchClient.cs" /> <Compile Include="Clients\ObservableSearchClient.cs" />
<Compile Include="Clients\ObservableDeploymentsClient.cs" />
<Compile Include="Clients\IObservableDeploymentsClient.cs" />
<Compile Include="Clients\IObservableDeploymentStatusClient.cs" />
<Compile Include="Clients\ObservableDeploymentStatusClient.cs" />
<Compile Include="Clients\IObservableWatchedClient.cs" /> <Compile Include="Clients\IObservableWatchedClient.cs" />
<Compile Include="Clients\ObservableWatchedClient.cs" /> <Compile Include="Clients\ObservableWatchedClient.cs" />
<Compile Include="Clients\IObservableFollowersClient.cs" /> <Compile Include="Clients\IObservableFollowersClient.cs" />
<Compile Include="Clients\ObservableFollowersClient.cs" /> <Compile Include="Clients\ObservableFollowersClient.cs" />
<Compile Include="Clients\IObservablePullRequestsClient.cs" /> <Compile Include="Clients\IObservablePullRequestsClient.cs" />
<Compile Include="Clients\ObservablePullRequestsClient.cs" /> <Compile Include="Clients\ObservablePullRequestsClient.cs" />
<Compile Include="Clients\IObservableUserEmailsClient.cs" />
<Compile Include="Clients\ObservableUserEmailsClient.cs" />
<Compile Include="Clients\IObservableStatisticsClient.cs" />
<Compile Include="Clients\ObservableStatisticsClient.cs" />
<Compile Include="Clients\IObservableBlobsClient.cs" />
<Compile Include="Clients\IObservableIssuesLabelsClient.cs" />
<Compile Include="Clients\IObservableTeamsClient.cs" />
<Compile Include="Clients\ObservableTeamsClient.cs" />
<Compile Include="Clients\ObservableIssuesLabelsClient.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup> <ItemGroup>

View File

@@ -44,21 +44,17 @@
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Net" /> <Reference Include="System.Net" />
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
<Reference Include="System.Reactive.Core, Version=2.1.30214.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="System.Reactive.Core">
<SpecificVersion>False</SpecificVersion> <HintPath>..\packages\Rx-Core.2.2.2\lib\net45\System.Reactive.Core.dll</HintPath>
<HintPath>..\packages\Rx-Core.2.1.30214.0\lib\Net40\System.Reactive.Core.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Reactive.Interfaces, Version=2.1.30214.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="System.Reactive.Interfaces">
<SpecificVersion>False</SpecificVersion> <HintPath>..\packages\Rx-Interfaces.2.2.2\lib\net45\System.Reactive.Interfaces.dll</HintPath>
<HintPath>..\packages\Rx-Interfaces.2.1.30214.0\lib\Net40\System.Reactive.Interfaces.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Reactive.Linq, Version=2.1.30214.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="System.Reactive.Linq">
<SpecificVersion>False</SpecificVersion> <HintPath>..\packages\Rx-Linq.2.2.2\lib\net45\System.Reactive.Linq.dll</HintPath>
<HintPath>..\packages\Rx-Linq.2.1.30214.0\lib\Net40\System.Reactive.Linq.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Reactive.PlatformServices, Version=2.1.30214.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="System.Reactive.PlatformServices">
<SpecificVersion>False</SpecificVersion> <HintPath>..\packages\Rx-PlatformServices.2.2.3\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
<HintPath>..\packages\Rx-PlatformServices.2.1.30214.0\lib\Net40\System.Reactive.PlatformServices.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
@@ -73,10 +69,18 @@
<Compile Include="..\SolutionInfo.cs"> <Compile Include="..\SolutionInfo.cs">
<Link>Properties\SolutionInfo.cs</Link> <Link>Properties\SolutionInfo.cs</Link>
</Compile> </Compile>
<Compile Include="Clients\IObservableDeploymentsClient.cs" />
<Compile Include="Clients\IObservableDeploymentStatusClient.cs" />
<Compile Include="Clients\ObservableDeploymentsClient.cs" />
<Compile Include="Clients\ObservableDeploymentStatusClient.cs" />
<Compile Include="Clients\IObservableUserEmailsClient.cs" />
<Compile Include="Clients\IObservableIssuesLabelsClient.cs" />
<Compile Include="Clients\IObservableWatchedClient.cs" /> <Compile Include="Clients\IObservableWatchedClient.cs" />
<Compile Include="Clients\IObservableFollowersClient.cs" /> <Compile Include="Clients\IObservableFollowersClient.cs" />
<Compile Include="Clients\IObservableStatisticsClient.cs" />
<Compile Include="Clients\ObservableIssuesLabelsClient.cs" />
<Compile Include="Clients\ObservableSearchClient.cs" /> <Compile Include="Clients\ObservableSearchClient.cs" />
<Compile Include="Clients\IObservableBlobClient.cs" /> <Compile Include="Clients\IObservableBlobsClient.cs" />
<Compile Include="Clients\IObservableGistCommentsClient.cs" /> <Compile Include="Clients\IObservableGistCommentsClient.cs" />
<Compile Include="Clients\IObservableGistsClient.cs" /> <Compile Include="Clients\IObservableGistsClient.cs" />
<Compile Include="Clients\IObservableReferencesClient.cs" /> <Compile Include="Clients\IObservableReferencesClient.cs" />
@@ -86,8 +90,8 @@
<Compile Include="Clients\ObservableReferencesClient.cs" /> <Compile Include="Clients\ObservableReferencesClient.cs" />
<Compile Include="Clients\ObservableRepoCollaboratorsClient.cs" /> <Compile Include="Clients\ObservableRepoCollaboratorsClient.cs" />
<Compile Include="Clients\IObservableRepoCollaboratorsClient.cs" /> <Compile Include="Clients\IObservableRepoCollaboratorsClient.cs" />
<Compile Include="Clients\ObservableOrganizationTeamsClient.cs" /> <Compile Include="Clients\ObservableTeamsClient.cs" />
<Compile Include="Clients\IObservableOrganizationTeamsClient.cs" /> <Compile Include="Clients\IObservableTeamsClient.cs" />
<Compile Include="Clients\IObservableCommitsClient.cs" /> <Compile Include="Clients\IObservableCommitsClient.cs" />
<Compile Include="Clients\IObservableStarredClient.cs" /> <Compile Include="Clients\IObservableStarredClient.cs" />
<Compile Include="Clients\ObservableCommitsClient.cs" /> <Compile Include="Clients\ObservableCommitsClient.cs" />
@@ -121,9 +125,11 @@
<Compile Include="Clients\ObservableRepositoriesClient.cs" /> <Compile Include="Clients\ObservableRepositoriesClient.cs" />
<Compile Include="Clients\ObservableSshKeysClient.cs" /> <Compile Include="Clients\ObservableSshKeysClient.cs" />
<Compile Include="Clients\ObservableStarredClient.cs" /> <Compile Include="Clients\ObservableStarredClient.cs" />
<Compile Include="Clients\ObservableStatisticsClient.cs" />
<Compile Include="Clients\ObservableTagsClient.cs" /> <Compile Include="Clients\ObservableTagsClient.cs" />
<Compile Include="Clients\ObservableTreesClient.cs" /> <Compile Include="Clients\ObservableTreesClient.cs" />
<Compile Include="Clients\ObservableFollowersClient.cs" /> <Compile Include="Clients\ObservableFollowersClient.cs" />
<Compile Include="Clients\ObservableUserEmailsClient.cs" />
<Compile Include="Clients\ObservableUsersClient.cs" /> <Compile Include="Clients\ObservableUsersClient.cs" />
<Compile Include="Clients\IObservableAssigneesClient.cs" /> <Compile Include="Clients\IObservableAssigneesClient.cs" />
<Compile Include="Clients\IObservableNotificationsClient.cs" /> <Compile Include="Clients\IObservableNotificationsClient.cs" />

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Rx-Core" version="2.1.30214.0" targetFramework="net40" requireReinstallation="True" /> <package id="Rx-Core" version="2.2.2" targetFramework="net45" />
<package id="Rx-Interfaces" version="2.1.30214.0" targetFramework="net40" requireReinstallation="True" /> <package id="Rx-Interfaces" version="2.2.2" targetFramework="net45" />
<package id="Rx-Linq" version="2.1.30214.0" targetFramework="net40" requireReinstallation="True" /> <package id="Rx-Linq" version="2.2.2" targetFramework="net45" />
<package id="Rx-Main" version="2.1.30214.0" targetFramework="net40" /> <package id="Rx-Main" version="2.2.2" targetFramework="net45" />
<package id="Rx-PlatformServices" version="2.1.30214.0" targetFramework="net40" requireReinstallation="True" /> <package id="Rx-PlatformServices" version="2.2.3" targetFramework="net45" />
</packages> </packages>

View File

@@ -0,0 +1,38 @@
using System;
using System.Diagnostics;
using System.Linq;
using Octokit.Tests.Helpers;
using Xunit;
using Xunit.Extensions;
namespace Octokit.Tests.Conventions
{
public class DebuggerDisplayOnModels
{
[Fact]
public void CheckModelsForDebuggerDisplayAttributeExample()
{
CheckModelsForDebuggerDisplayAttribute(typeof(IAuthorizationsClient));
}
[Theory]
[ClassData(typeof(ClientInterfaces))]
public void CheckModelsForDebuggerDisplayAttribute(Type clientInterface)
{
var methods = clientInterface.GetMethods();
var modelTypes =
from modelType in
(from type in (
from method in methods from parameter in method.GetParameters() select parameter.ParameterType
).Union(
from method in methods select method.ReturnType)
select type.GetTypeInfo().Type)
where TypeExtensions.IsModel(modelType)
select modelType;
foreach(var modelType in modelTypes.Distinct())
{
AssertEx.HasAttribute<DebuggerDisplayAttribute>(modelType);
}
}
}
}

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{5345E2E6-4E7C-40F8-831B-E491F6051D3C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Octokit.Tests.Conventions</RootNamespace>
<AssemblyName>Octokit.Tests.Conventions</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Reactive.Core">
<HintPath>..\packages\Rx-Core.2.2.2\lib\net45\System.Reactive.Core.dll</HintPath>
</Reference>
<Reference Include="System.Reactive.Interfaces">
<HintPath>..\packages\Rx-Interfaces.2.2.2\lib\net45\System.Reactive.Interfaces.dll</HintPath>
</Reference>
<Reference Include="xunit">
<HintPath>..\packages\xunit.1.9.2\lib\net20\xunit.dll</HintPath>
</Reference>
<Reference Include="xunit.extensions">
<HintPath>..\packages\xunit.extensions.1.9.2\lib\net20\xunit.extensions.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="DebuggerDisplayOnModels.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SyncObservableClients.cs" />
<Compile Include="TypeExtensions.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Octokit.Reactive\Octokit.Reactive.csproj">
<Project>{674b69b8-0780-4d54-ae2b-c15821fa51cb}</Project>
<Name>Octokit.Reactive</Name>
</ProjectReference>
<ProjectReference Include="..\Octokit.Tests\Octokit.Tests.csproj">
<Project>{149448d4-c2f2-4df9-86bd-03e3272f093b}</Project>
<Name>Octokit.Tests</Name>
</ProjectReference>
<ProjectReference Include="..\Octokit\Octokit.csproj">
<Project>{08dd4305-7787-4823-a53f-4d0f725a07f3}</Project>
<Name>Octokit</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Octokit.Tests.Conventions")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Octokit.Tests.Conventions")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("12127138-325b-4d55-a4f9-a3f915582e6f")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,119 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reflection;
using Octokit.Tests.Helpers;
using Xunit;
using Xunit.Extensions;
using Xunit.Sdk;
namespace Octokit.Tests.Conventions
{
public class SyncObservableClients
{
[Fact]
private void CheckObservableClientExample()
{
CheckObservableClients(typeof(ISearchClient));
}
[Theory]
[ClassData(typeof(ClientInterfaces))]
private void CheckObservableClients(Type clientInterface)
{
var observableClient = clientInterface.GetObservableClientInterface();
var mainMethods = clientInterface.GetMethodsOrdered();
var observableMethods = observableClient.GetMethodsOrdered();
var mainNames = Array.ConvertAll(mainMethods, m => m.Name);
var observableNames = Array.ConvertAll(observableMethods, m => m.Name);
AssertEx.Empty(observableNames.Except(mainNames), "Extra observable methods");
AssertEx.Empty(mainNames.Except(observableNames), "Missing observable methods");
int index = 0;
foreach(var mainMethod in mainMethods)
{
var observableMethod = observableMethods[index];
AssertEx.WithMessage(() => CheckMethod(mainMethod, observableMethod), "Invalid signature for " + observableMethod);
index++;
}
}
private static void CheckMethod(MethodInfo mainMethod, MethodInfo observableMethod)
{
Assert.Equal(mainMethod.MemberType, observableMethod.MemberType);
Assert.Equal(mainMethod.Name, observableMethod.Name);
CheckParameters(mainMethod, observableMethod);
CheckReturnValue(mainMethod, observableMethod);
}
private static void CheckReturnValue(MethodInfo mainMethod, MethodInfo observableMethod)
{
var mainReturnType = mainMethod.ReturnType;
var observableReturnType = observableMethod.ReturnType;
var expectedType = GetObservableExpectedType(mainReturnType);
Assert.Equal(expectedType, observableReturnType);
}
private static Type GetObservableExpectedType(Type mainType)
{
var typeInfo = mainType.GetTypeInfo();
switch(typeInfo.TypeCategory)
{
case TypeCategory.ClientInterface:
// client interface - IClient => IObservableClient
return mainType.GetObservableClientInterface();
case TypeCategory.Task:
// void - Task => IObservable<Unit>
return typeof(IObservable<Unit>);
case TypeCategory.GenericTask:
// single item - Task<TResult> => IObservable<TResult>
case TypeCategory.ReadOnlyList:
// list - Task<IReadOnlyList<TResult>> => IObservable<TResult>
return typeof(IObservable<>).MakeGenericType(typeInfo.Type);
case TypeCategory.Other:
return mainType;
default:
throw new Exception("Unknown type category " + typeInfo.TypeCategory);
}
}
private static void CheckParameters(MethodInfo mainMethod, MethodInfo observableMethod)
{
var mainParameters = mainMethod.GetParametersOrdered();
var observableParameters = observableMethod.GetParametersOrdered();
Assert.Equal(mainParameters.Length, observableParameters.Length);
int index = 0;
foreach(var mainParameter in mainParameters)
{
var observableParameter = observableParameters[index];
Assert.Equal(mainParameter.Name, observableParameter.Name);
var mainType = mainParameter.ParameterType;
var typeInfo = mainType.GetTypeInfo();
var expectedType = GetObservableExpectedType(mainType);
Assert.Equal(expectedType, observableParameter.ParameterType);
index++;
}
}
}
public class ClientInterfaces : IEnumerable<object[]>
{
private readonly IEnumerable<object[]> data = GetClientInterfaces();
public static IEnumerable<object[]> GetClientInterfaces()
{
return typeof(IEventsClient).Assembly.ExportedTypes.Where(TypeExtensions.IsClientInterface).Select(type => new[] { type });
}
public IEnumerator<object[]> GetEnumerator()
{
return data.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View File

@@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Octokit.Reactive;
namespace Octokit.Tests.Conventions
{
public static class TypeExtensions
{
const string ClientSuffix = "Client";
const string ObservablePrefix = "IObservable";
const int RealNameIndex = 1;
public static ParameterInfo[] GetParametersOrdered(this MethodInfo method)
{
return method.GetParameters().OrderBy(p => p.Name).ToArray();
}
public static MethodInfo[] GetMethodsOrdered(this Type type)
{
return type.GetMethods().OrderBy(m => m.Name).ToArray();
}
public static TypeInfo GetTypeInfo(this Type type)
{
var typeInfo = new TypeInfo { Type = type, TypeCategory = TypeCategory.Other };
if(type.IsClientInterface())
{
typeInfo.TypeCategory = TypeCategory.ClientInterface;
}
else if(type.IsTask())
{
if(!type.IsGenericType)
{
typeInfo.TypeCategory = TypeCategory.Task;
}
else
{
var taskResultType = type.GetGenericArgument();
if(taskResultType.IsList())
{
typeInfo.TypeCategory = TypeCategory.ReadOnlyList;
typeInfo.Type = taskResultType.GetGenericArgument();
}
else
{
typeInfo.TypeCategory = TypeCategory.GenericTask;
typeInfo.Type = taskResultType;
}
}
}
return typeInfo;
}
public static bool IsModel(this Type type)
{
return !type.IsInterface && type.Assembly == typeof(AuthorizationUpdate).Assembly;
}
public static bool IsClientInterface(this Type type)
{
return type.IsInterface && type.Name.EndsWith(ClientSuffix) && type.Namespace == typeof(IEventsClient).Namespace;
}
public static Type GetObservableClientInterface(this Type type)
{
var observableClient = typeof(IObservableEventsClient);
var observableClientName = observableClient.Namespace + "." + ObservablePrefix + type.Name.Substring(RealNameIndex);
var observableInterface = observableClient.Assembly.GetType(observableClientName);
if(observableInterface == null)
{
throw new Exception("Cannot find observable interface "+observableClientName);
}
return observableInterface;
}
public static bool IsTask(this Type type)
{
return typeof(Task).IsAssignableFrom(type);
}
public static bool IsList(this Type type)
{
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IReadOnlyList<>);
}
public static Type GetGenericArgument(this Type type)
{
return type.GetGenericArguments()[0];
}
}
public enum TypeCategory { Other, Task, GenericTask, ReadOnlyList, ClientInterface }
public struct TypeInfo
{
public Type Type { get; set; }
public TypeCategory TypeCategory { get; set; }
}
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Rx-Core" version="2.2.2" targetFramework="net45" />
<package id="Rx-Interfaces" version="2.2.2" targetFramework="net45" />
<package id="xunit" version="1.9.2" targetFramework="net45" />
<package id="xunit.extensions" version="1.9.2" targetFramework="net45" />
</packages>

View File

@@ -0,0 +1,88 @@
using Octokit;
using Octokit.Tests.Integration;
using System;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Xunit;
public class DeploymentStatusClientTests : IDisposable
{
IGitHubClient _gitHubClient;
IDeploymentsClient _deploymentsClient;
Repository _repository;
Commit _commit;
Deployment _deployment;
string _repositoryOwner;
public DeploymentStatusClientTests()
{
_gitHubClient = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
_deploymentsClient = _gitHubClient.Deployment;
var newRepository = new NewRepository
{
Name = Helper.MakeNameWithTimestamp("public-repo"),
AutoInit = true
};
_repository = _gitHubClient.Repository.Create(newRepository).Result;
_repositoryOwner = _repository.Owner.Login;
var blob = new NewBlob
{
Content = "Hello World!",
Encoding = EncodingType.Utf8
};
var blobResult = _gitHubClient.GitDatabase.Blob.Create(_repositoryOwner, _repository.Name, blob).Result;
var newTree = new NewTree();
newTree.Tree.Add(new NewTreeItem
{
Type = TreeType.Blob,
Mode = FileMode.File,
Path = "README.md",
Sha = blobResult.Sha
});
var treeResult = _gitHubClient.GitDatabase.Tree.Create(_repositoryOwner, _repository.Name, newTree).Result;
var newCommit = new NewCommit("test-commit", treeResult.Sha);
_commit = _gitHubClient.GitDatabase.Commit.Create(_repositoryOwner, _repository.Name, newCommit).Result;
var newDeployment = new NewDeployment { Ref = _commit.Sha };
_deployment = _deploymentsClient.Create(_repositoryOwner, _repository.Name, newDeployment).Result;
}
[IntegrationTest]
public async Task CanCreateDeploymentStatus()
{
var newStatus = new NewDeploymentStatus { State = DeploymentState.Success };
var status = await _deploymentsClient.Status.Create(_repositoryOwner, _repository.Name, _deployment.Id, newStatus);
Assert.NotNull(status);
Assert.Equal(DeploymentState.Success, status.State);
}
[IntegrationTest]
public async Task CanReadDeploymentStatuses()
{
var newStatus = new NewDeploymentStatus { State = DeploymentState.Success };
await _deploymentsClient.Status.Create(_repositoryOwner, _repository.Name, _deployment.Id, newStatus);
var statuses = await _deploymentsClient.Status.GetAll(_repositoryOwner, _repository.Name, _deployment.Id);
Assert.NotEmpty(statuses);
Assert.Equal(DeploymentState.Success, statuses[0].State);
}
public void Dispose()
{
Helper.DeleteRepo(_repository);
}
}

View File

@@ -0,0 +1,81 @@
using Octokit;
using Octokit.Tests.Integration;
using System;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Xunit;
public class DeploymentsClientTests : IDisposable
{
IGitHubClient _gitHubClient;
IDeploymentsClient _deploymentsClient;
Repository _repository;
Commit _commit;
string _repositoryOwner;
public DeploymentsClientTests()
{
_gitHubClient = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
_deploymentsClient = _gitHubClient.Deployment;
var newRepository = new NewRepository
{
Name = Helper.MakeNameWithTimestamp("public-repo"),
AutoInit = true
};
_repository = _gitHubClient.Repository.Create(newRepository).Result;
_repositoryOwner = _repository.Owner.Login;
var blob = new NewBlob
{
Content = "Hello World!",
Encoding = EncodingType.Utf8
};
var blobResult = _gitHubClient.GitDatabase.Blob.Create(_repositoryOwner, _repository.Name, blob).Result;
var newTree = new NewTree();
newTree.Tree.Add(new NewTreeItem
{
Type = TreeType.Blob,
Mode = FileMode.File,
Path = "README.md",
Sha = blobResult.Sha
});
var treeResult = _gitHubClient.GitDatabase.Tree.Create(_repositoryOwner, _repository.Name, newTree).Result;
var newCommit = new NewCommit("test-commit", treeResult.Sha);
_commit = _gitHubClient.GitDatabase.Commit.Create(_repositoryOwner, _repository.Name, newCommit).Result;
}
[IntegrationTest]
public async Task CanCreateDeployment()
{
var newDeployment = new NewDeployment { Ref = _commit.Sha };
var deployment = await _deploymentsClient.Create(_repositoryOwner, _repository.Name, newDeployment);
Assert.NotNull(deployment);
}
[IntegrationTest]
public async Task CanGetDeployments()
{
var newDeployment = new NewDeployment { Ref = _commit.Sha };
await _deploymentsClient.Create(_repositoryOwner, _repository.Name, newDeployment);
var deployments = await _deploymentsClient.GetAll(_repositoryOwner, _repository.Name);
Assert.NotEmpty(deployments);
}
public void Dispose()
{
Helper.DeleteRepo(_repository);
}
}

View File

@@ -44,8 +44,8 @@ public class ReferencesClientTests : IDisposable
[IntegrationTest] [IntegrationTest]
public async Task WhenReferenceDoesNotExistAnExeptionIsThrown() public async Task WhenReferenceDoesNotExistAnExeptionIsThrown()
{ {
AssertEx.Throws<NotFoundException>( await AssertEx.Throws<NotFoundException>(
async () => await _fixture.Get("octokit", "octokit.net", "heads/foofooblahblah")); () => _fixture.Get("octokit", "octokit.net", "heads/foofooblahblah"));
} }
[IntegrationTest] [IntegrationTest]

View File

@@ -1,4 +1,6 @@
using System.Net.Http.Headers; using System;
using System.Linq;
using System.Net.Http.Headers;
using System.Threading.Tasks; using System.Threading.Tasks;
using Octokit; using Octokit;
using Octokit.Tests.Integration; using Octokit.Tests.Integration;
@@ -299,6 +301,116 @@ public class RepositoriesClientTests
// TODO: Add a test for the team_id param once an overload that takes an oranization is added // TODO: Add a test for the team_id param once an overload that takes an oranization is added
} }
private static IGitHubClient CreateGitHubClient()
{
return new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
}
public class TheEditMethod : IDisposable
{
Repository _repository;
[IntegrationTest]
public async Task UpdatesName()
{
var github = CreateGitHubClient();
var repoName = Helper.MakeNameWithTimestamp("public-repo");
_repository = await github.Repository.Create(new NewRepository { Name = repoName, AutoInit = true });
var updatedName = Helper.MakeNameWithTimestamp("updated-repo");
var update = new RepositoryUpdate { Name = updatedName };
_repository = await github.Repository.Edit(Helper.UserName, repoName, update);
Assert.Equal(update.Name, _repository.Name);
}
[IntegrationTest]
public async Task UpdatesDescription()
{
var github = CreateGitHubClient();
var repoName = Helper.MakeNameWithTimestamp("public-repo");
_repository = await github.Repository.Create(new NewRepository { Name = repoName, AutoInit = true });
var update = new RepositoryUpdate { Name = repoName, Description = "Updated description" };
_repository = await github.Repository.Edit(Helper.UserName, repoName, update);
Assert.Equal("Updated description", _repository.Description);
}
[IntegrationTest]
public async Task UpdatesHomepage()
{
var github = CreateGitHubClient();
var repoName = Helper.MakeNameWithTimestamp("public-repo");
_repository = await github.Repository.Create(new NewRepository { Name = repoName, AutoInit = true });
var update = new RepositoryUpdate { Name = repoName, Homepage = "http://aUrl.to/nowhere" };
_repository = await github.Repository.Edit(Helper.UserName, repoName, update);
Assert.Equal("http://aUrl.to/nowhere", _repository.Homepage);
}
[IntegrationTest]
public async Task UpdatesPrivate()
{
var github = CreateGitHubClient();
var repoName = Helper.MakeNameWithTimestamp("public-repo");
_repository = await github.Repository.Create(new NewRepository { Name = repoName, AutoInit = true });
var update = new RepositoryUpdate { Name = repoName, Private = true };
_repository = await github.Repository.Edit(Helper.UserName, repoName, update);
Assert.Equal(true, _repository.Private);
}
[IntegrationTest]
public async Task UpdatesHasDownloads()
{
var github = CreateGitHubClient();
var repoName = Helper.MakeNameWithTimestamp("public-repo");
_repository = await github.Repository.Create(new NewRepository { Name = repoName, AutoInit = true });
var update = new RepositoryUpdate { Name = repoName, HasDownloads = false };
_repository = await github.Repository.Edit(Helper.UserName, repoName, update);
Assert.Equal(false, _repository.HasDownloads);
}
[IntegrationTest]
public async Task UpdatesHasIssues()
{
var github = CreateGitHubClient();
var repoName = Helper.MakeNameWithTimestamp("public-repo");
_repository = await github.Repository.Create(new NewRepository { Name = repoName, AutoInit = true });
var update = new RepositoryUpdate { Name = repoName, HasIssues = false };
_repository = await github.Repository.Edit(Helper.UserName, repoName, update);
Assert.Equal(false, _repository.HasIssues);
}
[IntegrationTest]
public async Task UpdatesHasWiki()
{
var github = CreateGitHubClient();
var repoName = Helper.MakeNameWithTimestamp("public-repo");
_repository = await github.Repository.Create(new NewRepository { Name = repoName, AutoInit = true });
var update = new RepositoryUpdate { Name = repoName, HasWiki = false };
_repository = await github.Repository.Edit(Helper.UserName, repoName, update);
Assert.Equal(false, _repository.HasWiki);
}
public void Dispose()
{
Helper.DeleteRepo(_repository);
}
}
public class TheDeleteMethod public class TheDeleteMethod
{ {
[IntegrationTest] [IntegrationTest]
@@ -395,4 +507,58 @@ public class RepositoriesClientTests
Assert.Contains("<p><strong>WARNING: This is some haacky code.", readmeHtml); Assert.Contains("<p><strong>WARNING: This is some haacky code.", readmeHtml);
} }
} }
public class TheGetAllContributorsMethod
{
[IntegrationTest]
public async Task GetsContributors()
{
var github = CreateGitHubClient();
var contributors = await github.Repository.GetAllContributors("octokit", "octokit.net");
Assert.True(contributors.Any(c => c.Login == "pmacn"));
}
}
public class TheGetAllLanguagesMethod
{
[IntegrationTest]
public async Task GetsLanguages()
{
var github = CreateGitHubClient();
var languages = await github.Repository.GetAllLanguages("octokit", "octokit.net");
Assert.NotEmpty(languages);
Assert.True(languages.Any(l => l.Name == "C#"));
}
}
public class TheGetAllTagsMethod
{
[IntegrationTest]
public async Task GetsTags()
{
var github = CreateGitHubClient();
var tags = await github.Repository.GetAllTags("octokit", "octokit.net");
Assert.True(tags.Any(t => t.Name == "v0.1.0"));
}
}
public class TheGetBranchMethod
{
[IntegrationTest]
public async Task GetsABranch()
{
var github = CreateGitHubClient();
var branch = await github.Repository.GetBranch("octokit", "octokit.net", "master");
Assert.NotNull(branch);
Assert.Equal("master", branch.Name);
}
}
} }

View File

@@ -0,0 +1,131 @@
using System.Linq;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Xunit;
namespace Octokit.Tests.Integration.Clients
{
public class StatisticsClientTests
{
readonly IGitHubClient _client;
readonly ICommitsClient _fixture;
public StatisticsClientTests()
{
_client = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
_fixture = _client.GitDatabase.Commit;
}
[IntegrationTest]
public async Task CanCreateAndRetrieveCommit()
{
var repository = await CreateRepository();
await CommitToRepository(repository);
var contributors = await _client.Statistics.GetContributors(repository.Owner, repository.Name);
Assert.NotNull(contributors);
Assert.True(contributors.Count() == 1);
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);
}
[IntegrationTest]
public async Task CanGetCommitActivityForTheLastYear()
{
var repository = await CreateRepository();
await CommitToRepository(repository);
var commitActivities = await _client.Statistics.GetCommitActivity(repository.Owner, repository.Name);
Assert.NotNull(commitActivities);
Assert.True(commitActivities.Activity.Count() == 52);
var thisWeek = commitActivities.Activity.Last();
Assert.True(thisWeek.Total == 1);
Assert.NotNull(thisWeek.Days);
}
[IntegrationTest]
public async Task CanGetAdditionsAndDeletionsPerWeek()
{
var repository = await CreateRepository();
await CommitToRepository(repository);
var commitActivities = await _client.Statistics.GetCodeFrequency(repository.Owner, repository.Name);
Assert.NotNull(commitActivities);
Assert.True(commitActivities.AdditionsAndDeletionsByWeek.Any());
}
[IntegrationTest]
public async Task CanGetParticipationStatistics()
{
var repository = await CreateRepository();
await CommitToRepository(repository);
var weeklyCommitCounts = await _client.Statistics.GetParticipation(repository.Owner, repository.Name);
Assert.NotNull(weeklyCommitCounts);
Assert.NotNull(weeklyCommitCounts.All);
Assert.NotNull(weeklyCommitCounts.Owner);
}
[IntegrationTest]
public async Task CanGetPunchCardForRepository()
{
var repository = await CreateRepository();
await CommitToRepository(repository);
var punchCard = await _client.Statistics.GetPunchCard(repository.Owner, repository.Name);
Assert.NotNull(punchCard);
Assert.NotNull(punchCard.PunchPoints);
}
async Task<RepositorySummary> CreateRepository()
{
var repoName = Helper.MakeNameWithTimestamp("public-repo");
var repository = await _client.Repository.Create(new NewRepository { Name = repoName, AutoInit = true });
return new RepositorySummary
{
Owner = repository.Owner.Login,
Name = repoName
};
}
async Task<Commit> CommitToRepository(RepositorySummary repositorySummary)
{
var owner = repositorySummary.Owner;
var repository = repositorySummary.Name;
var blob = new NewBlob
{
Content = "Hello World!",
Encoding = EncodingType.Utf8
};
var blobResult = await _client.GitDatabase.Blob.Create(owner, repository, blob);
var newTree = new NewTree();
newTree.Tree.Add(new NewTreeItem
{
Type = TreeType.Blob,
Mode = FileMode.File,
Path = "README.md",
Sha = blobResult.Sha
});
var treeResult = await _client.GitDatabase.Tree.Create(owner, repository, newTree);
var newCommit = new NewCommit("test-commit", treeResult.Sha);
var commit = await _fixture.Create(owner, repository, newCommit);
return commit;
}
class RepositorySummary
{
public string Name { get; set; }
public string Owner { get; set; }
}
}
}

View File

@@ -0,0 +1,21 @@
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Xunit;
namespace Octokit.Tests.Integration.Clients
{
public class UserEmailsClientTests
{
[IntegrationTest]
public async Task CanGetEmail()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
var emails = await github.User.Email.GetAll();
Assert.NotEmpty(emails);
}
}
}

View File

@@ -99,22 +99,4 @@ public class UsersClientTests
Assert.Equal(HttpStatusCode.Unauthorized, e.StatusCode); Assert.Equal(HttpStatusCode.Unauthorized, e.StatusCode);
} }
} }
public class TheGetEmailsMethod
{
[IntegrationTest]
public async Task RetrievesEmailsForUser()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
var emails = await github.User.GetEmails();
Assert.NotEmpty(emails);
var email = emails.First();
Assert.True(email.Primary);
}
}
} }

View File

@@ -36,13 +36,13 @@
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
<Reference Include="System.Reactive.Core"> <Reference Include="System.Reactive.Core">
<HintPath>..\packages\Rx-Core.2.1.30214.0\lib\Net45\System.Reactive.Core.dll</HintPath> <HintPath>..\packages\Rx-Core.2.2.2\lib\net45\System.Reactive.Core.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Reactive.Interfaces"> <Reference Include="System.Reactive.Interfaces">
<HintPath>..\packages\Rx-Interfaces.2.1.30214.0\lib\Net45\System.Reactive.Interfaces.dll</HintPath> <HintPath>..\packages\Rx-Interfaces.2.2.2\lib\net45\System.Reactive.Interfaces.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Reactive.Linq"> <Reference Include="System.Reactive.Linq">
<HintPath>..\packages\Rx-Linq.2.1.30214.0\lib\Net45\System.Reactive.Linq.dll</HintPath> <HintPath>..\packages\Rx-Linq.2.2.2\lib\net45\System.Reactive.Linq.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
@@ -62,6 +62,8 @@
<Compile Include="Clients\BranchesClientTests.cs" /> <Compile Include="Clients\BranchesClientTests.cs" />
<Compile Include="Clients\CommitsClientTests.cs" /> <Compile Include="Clients\CommitsClientTests.cs" />
<Compile Include="Clients\CommitStatusClientTests.cs" /> <Compile Include="Clients\CommitStatusClientTests.cs" />
<Compile Include="Clients\DeploymentsClientTests.cs" />
<Compile Include="Clients\DeploymentStatusClientTests.cs" />
<Compile Include="Clients\EventsClientTests.cs" /> <Compile Include="Clients\EventsClientTests.cs" />
<Compile Include="Clients\IssuesLabelsClientTests.cs" /> <Compile Include="Clients\IssuesLabelsClientTests.cs" />
<Compile Include="Clients\GistsClientTests.cs" /> <Compile Include="Clients\GistsClientTests.cs" />
@@ -69,7 +71,9 @@
<Compile Include="Clients\MilestonesClientTests.cs" /> <Compile Include="Clients\MilestonesClientTests.cs" />
<Compile Include="Clients\PullRequestsClientTests.cs" /> <Compile Include="Clients\PullRequestsClientTests.cs" />
<Compile Include="Clients\ReferencesClientTests.cs" /> <Compile Include="Clients\ReferencesClientTests.cs" />
<Compile Include="Clients\StatisticsClientTests.cs" />
<Compile Include="Clients\TreeClientTests.cs" /> <Compile Include="Clients\TreeClientTests.cs" />
<Compile Include="Clients\UserEmailsClientTests.cs" />
<Compile Include="Clients\FollowersClientTests.cs" /> <Compile Include="Clients\FollowersClientTests.cs" />
<Compile Include="IntegrationTestAttribute.cs" /> <Compile Include="IntegrationTestAttribute.cs" />
<Compile Include="Clients\IssuesClientTests.cs" /> <Compile Include="Clients\IssuesClientTests.cs" />
@@ -82,6 +86,7 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Helper.cs" /> <Compile Include="Helper.cs" />
<Compile Include="Clients\UsersClientTests.cs" /> <Compile Include="Clients\UsersClientTests.cs" />
<Compile Include="Reactive\ObservableUserEmailsClientTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Octokit.Reactive\Octokit.Reactive.csproj"> <ProjectReference Include="..\Octokit.Reactive\Octokit.Reactive.csproj">

View File

@@ -0,0 +1,24 @@
using Octokit.Reactive;
using System.Net.Http.Headers;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Xunit;
namespace Octokit.Tests.Integration
{
public class ObservableUserEmailsClientTests
{
[IntegrationTest]
public async Task CanGetEmail()
{
var github = new GitHubClient(new ProductHeaderValue("OctokitTests"))
{
Credentials = Helper.Credentials
};
var client = new ObservableUserEmailsClient(github);
var email = await client.GetAll();
Assert.NotNull(email);
}
}
}

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Rx-Core" version="2.1.30214.0" targetFramework="net45" /> <package id="Rx-Core" version="2.2.2" targetFramework="net45" />
<package id="Rx-Interfaces" version="2.1.30214.0" targetFramework="net45" /> <package id="Rx-Interfaces" version="2.2.2" targetFramework="net45" />
<package id="Rx-Linq" version="2.1.30214.0" targetFramework="net45" /> <package id="Rx-Linq" version="2.2.2" targetFramework="net45" />
<package id="xunit" version="1.9.2" targetFramework="net45" /> <package id="xunit" version="1.9.2" targetFramework="net45" />
<package id="xunit.extensions" version="1.9.2" targetFramework="net45" /> <package id="xunit.extensions" version="1.9.2" targetFramework="net45" />
</packages> </packages>

View File

@@ -70,7 +70,7 @@ namespace Octokit.Tests.Clients
apiConnection.Connection.Returns(connection); apiConnection.Connection.Returns(connection);
var client = new AssigneesClient(apiConnection); var client = new AssigneesClient(apiConnection);
AssertEx.Throws<ApiException>(async () => await client.CheckAssignee("foo", "bar", "cody")); await AssertEx.Throws<ApiException>(() => client.CheckAssignee("foo", "bar", "cody"));
} }
[Fact] [Fact]

View File

@@ -127,7 +127,7 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task WrapsTwoFactorFailureWithTwoFactorException() public void WrapsTwoFactorFailureWithTwoFactorException()
{ {
var data = new NewAuthorization(); var data = new NewAuthorization();
var client = Substitute.For<IApiConnection>(); var client = Substitute.For<IApiConnection>();
@@ -139,8 +139,8 @@ namespace Octokit.Tests.Clients
}); });
var authEndpoint = new AuthorizationsClient(client); var authEndpoint = new AuthorizationsClient(client);
AssertEx.Throws<TwoFactorChallengeFailedException>(async () => Assert.Throws<TwoFactorChallengeFailedException>(() =>
await authEndpoint.GetOrCreateApplicationAuthentication("clientId", "secret", data)); authEndpoint.GetOrCreateApplicationAuthentication("clientId", "secret", data, "authenticationCode"));
} }
[Fact] [Fact]
@@ -222,8 +222,8 @@ namespace Octokit.Tests.Clients
"wrong-code") "wrong-code")
.Returns(_ => { throw new TwoFactorChallengeFailedException(); }); .Returns(_ => { throw new TwoFactorChallengeFailedException(); });
var exception = AssertEx.Throws<TwoFactorChallengeFailedException>(async () => var exception = await AssertEx.Throws<TwoFactorChallengeFailedException>(() =>
await client.GetOrCreateApplicationAuthentication( client.GetOrCreateApplicationAuthentication(
"clientId", "clientId",
"secret", "secret",
data, data,

View File

@@ -0,0 +1,146 @@
using NSubstitute;
using Octokit;
using Octokit.Tests.Helpers;
using System;
using System.Collections.Generic;
using Xunit;
using Xunit.Extensions;
using System.Threading.Tasks;
public class DeploymentStatusClientTests
{
const string expectedAcceptsHeader = "application/vnd.github.cannonball-preview+json";
public class TheGetAllMethod
{
[Fact]
public void EnsuresNonNullArguments()
{
var client = new DeploymentStatusClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.GetAll(null, "name", 1));
Assert.Throws<ArgumentNullException>(() => client.GetAll("owner", null, 1));
}
[Fact]
public void EnsuresNonEmptyArguments()
{
var client = new DeploymentStatusClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentException>(() => client.GetAll("", "name", 1));
Assert.Throws<ArgumentException>(() => client.GetAll("owner", "", 1));
}
[Theory]
[InlineData(" ")]
[InlineData("\n")]
[InlineData("\t")]
[InlineData(" ")]
[InlineData("\n\r")]
public void EnsureNonWhitespaceArguments(string whitespace)
{
var client = new DeploymentStatusClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentException>(() => client.GetAll(whitespace, "name", 1));
Assert.Throws<ArgumentException>(() => client.GetAll("owner", whitespace, 1));
}
[Fact]
public void RequestsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentStatusClient(connection);
var expectedUrl = "repos/owner/name/deployments/1/statuses";
client.GetAll("owner", "name", 1);
connection.Received().GetAll<DeploymentStatus>(Arg.Is<Uri>(u => u.ToString() == expectedUrl),
Arg.Any<IDictionary<string, string>>(),
Arg.Any<string>());
}
[Fact]
public void UsesPreviewAcceptHeader()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentStatusClient(connection);
client.GetAll("owner", "name", 1);
connection.Received().GetAll<DeploymentStatus>(Arg.Any<Uri>(),
Arg.Any<IDictionary<string, string>>(),
expectedAcceptsHeader);
}
}
public class TheCreateMethod
{
readonly NewDeploymentStatus newDeploymentStatus = new NewDeploymentStatus();
[Fact]
public void EnsuresNonNullArguments()
{
var client = new DeploymentStatusClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", 1, newDeploymentStatus));
Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, 1, newDeploymentStatus));
}
[Fact]
public void EnsuresNonEmptyArguments()
{
var client = new DeploymentStatusClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentException>(() => client.GetAll("", "name", 1));
Assert.Throws<ArgumentException>(() => client.GetAll("owner", "", 1));
}
[Theory]
[InlineData(" ")]
[InlineData("\n")]
[InlineData("\t")]
[InlineData(" ")]
[InlineData("\n\r")]
public void EnsureNonWhitespaceArguments(string whitespace)
{
var client = new DeploymentStatusClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentException>(() => client.Create(whitespace, "repo", 1, newDeploymentStatus));
Assert.Throws<ArgumentException>(() => client.Create("owner", whitespace, 1, newDeploymentStatus));
}
[Fact]
public void PostsToCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentStatusClient(connection);
var expectedUrl = "repos/owner/repo/deployments/1/statuses";
client.Create("owner", "repo", 1, newDeploymentStatus);
connection.Received().Post<DeploymentStatus>(Arg.Is<Uri>(u => u.ToString() == expectedUrl),
Arg.Any<NewDeploymentStatus>(),
Arg.Any<string>());
}
[Fact]
public void UsesPreviewAcceptHeader()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentStatusClient(connection);
client.Create("owner", "repo", 1, newDeploymentStatus);
connection.Received().Post<DeploymentStatus>(Arg.Any<Uri>(),
Arg.Any<NewDeploymentStatus>(),
expectedAcceptsHeader);
}
}
public class TheCtor
{
[Fact]
public void EnsuresArgument()
{
Assert.Throws<ArgumentNullException>(() => new DeploymentStatusClient(null));
}
}
}

View File

@@ -0,0 +1,165 @@
using NSubstitute;
using Octokit;
using Octokit.Tests.Helpers;
using System;
using System.Collections.Generic;
using Xunit;
using Xunit.Extensions;
public class DeploymentsClientTests
{
const string ExpectedAcceptHeader = "application/vnd.github.cannonball-preview+json";
public class TheGetAllMethod
{
[Fact]
public async void EnsuresNonNullArguments()
{
var client = new DeploymentsClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.GetAll(null, "name"));
Assert.Throws<ArgumentNullException>(() => client.GetAll("owner", null));
}
[Fact]
public async void EnsuresNonEmptyArguments()
{
var client = new DeploymentsClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentException>(() => client.GetAll("", "name"));
Assert.Throws<ArgumentException>(() => client.GetAll("owner", ""));
}
[Theory]
[InlineData(" ")]
[InlineData("\n")]
[InlineData("\t")]
[InlineData(" ")]
[InlineData("\n\r")]
public async void EnsuresNonWhitespaceArguments(string whitespace)
{
var client = new DeploymentsClient(Substitute.For<IApiConnection>());
await AssertEx.Throws<ArgumentException>(() => client.GetAll(whitespace, "name"));
await AssertEx.Throws<ArgumentException>(() => client.GetAll("owner", whitespace));
}
[Fact]
public void RequestsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentsClient(connection);
var expectedUrl = "repos/owner/name/deployments";
client.GetAll("owner", "name");
connection.Received(1).GetAll<Deployment>(Arg.Is<Uri>(u => u.ToString() == expectedUrl),
Arg.Any<IDictionary<string, string>>(),
Arg.Any<string>());
}
[Fact]
public void UsesPreviewAcceptsHeader()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentsClient(connection);
client.GetAll("owner", "name");
connection.Received().GetAll<Deployment>(Arg.Any<Uri>(),
Arg.Any<IDictionary<string, string>>(),
ExpectedAcceptHeader);
}
}
public class TheCreateMethod
{
readonly NewDeployment newDeployment = new NewDeployment { Ref = "aRef" };
[Fact]
public void EnsuresNonNullArguments()
{
var client = new DeploymentsClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(() => client.Create(null, "name", newDeployment));
AssertEx.Throws<ArgumentNullException>(() => client.Create("owner", null, newDeployment));
AssertEx.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
}
[Fact]
public void EnsuresNonEmptyArguments()
{
var client = new DeploymentsClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentException>(() => client.Create("", "name", newDeployment));
Assert.Throws<ArgumentException>(() => client.Create("owner", "", newDeployment));
}
[Theory]
[InlineData(" ")]
[InlineData("\n")]
[InlineData("\t")]
[InlineData(" ")]
[InlineData("\n\r")]
public void EnsuresNonWhitespaceArguments(string whitespace)
{
var client = new DeploymentsClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentException>(() => client.Create(whitespace, "name", newDeployment));
Assert.Throws<ArgumentException>(() => client.Create("owner", whitespace, newDeployment));
}
[Fact]
public void PostsToDeploymentsUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentsClient(connection);
var expectedUrl = "repos/owner/name/deployments";
client.Create("owner", "name", newDeployment);
connection.Received(1).Post<Deployment>(Arg.Is<Uri>(u => u.ToString() == expectedUrl),
Arg.Any<NewDeployment>(),
Arg.Any<string>());
}
[Fact]
public void PassesNewDeploymentRequest()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentsClient(connection);
client.Create("owner", "name", newDeployment);
connection.Received(1).Post<Deployment>(Arg.Any<Uri>(),
newDeployment,
Arg.Any<string>());
}
[Fact]
public void UsesPreviewAcceptsHeader()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentsClient(connection);
client.Create("owner", "name", newDeployment);
connection.Received().Post<Deployment>(Arg.Any<Uri>(),
Arg.Any<NewDeployment>(),
Arg.Is(ExpectedAcceptHeader));
}
}
public class TheCtor
{
[Fact]
public void EnsuresArgument()
{
Assert.Throws<ArgumentNullException>(() => new DeploymentsClient(null));
}
[Fact]
public void SetsStatusesClient()
{
var client = new DeploymentsClient(Substitute.For<IApiConnection>());
Assert.NotNull(client.Status);
}
}
}

View File

@@ -61,8 +61,8 @@ namespace Octokit.Tests.Clients
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new FollowersClient(connection); var client = new FollowersClient(connection);
AssertEx.Throws<ArgumentNullException>(async () => await client.GetAll(null)); Assert.Throws<ArgumentNullException>(() => client.GetAll(null));
AssertEx.Throws<ArgumentException>(async () => await client.GetAll("")); Assert.Throws<ArgumentException>(() => client.GetAll(""));
} }
} }
@@ -99,8 +99,8 @@ namespace Octokit.Tests.Clients
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new FollowersClient(connection); var client = new FollowersClient(connection);
AssertEx.Throws<ArgumentNullException>(async () => await client.GetFollowing(null)); Assert.Throws<ArgumentNullException>(() => client.GetFollowing(null));
AssertEx.Throws<ArgumentException>(async () => await client.GetFollowing("")); Assert.Throws<ArgumentException>(() => client.GetFollowing(""));
} }
} }
@@ -137,17 +137,17 @@ namespace Octokit.Tests.Clients
apiConnection.Connection.Returns(connection); apiConnection.Connection.Returns(connection);
var client = new FollowersClient(apiConnection); var client = new FollowersClient(apiConnection);
AssertEx.Throws<ApiException>(async () => await client.IsFollowingForCurrent("alfhenrik")); await AssertEx.Throws<ApiException>(() => client.IsFollowingForCurrent("alfhenrik"));
} }
[Fact] [Fact]
public void EnsuresNonNullArguments() public async Task EnsuresNonNullArguments()
{ {
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new FollowersClient(connection); var client = new FollowersClient(connection);
AssertEx.Throws<ArgumentNullException>(async () => await client.IsFollowingForCurrent(null)); await AssertEx.Throws<ArgumentNullException>(() => client.IsFollowingForCurrent(null));
AssertEx.Throws<ArgumentException>(async () => await client.IsFollowingForCurrent("")); await AssertEx.Throws<ArgumentException>(() => client.IsFollowingForCurrent(""));
} }
} }
@@ -184,19 +184,19 @@ namespace Octokit.Tests.Clients
apiConnection.Connection.Returns(connection); apiConnection.Connection.Returns(connection);
var client = new FollowersClient(apiConnection); var client = new FollowersClient(apiConnection);
AssertEx.Throws<ApiException>(async () => await client.IsFollowing("alfhenrik", "alfhenrik-test")); await AssertEx.Throws<ApiException>(() => client.IsFollowing("alfhenrik", "alfhenrik-test"));
} }
[Fact] [Fact]
public void EnsuresNonNullArguments() public async Task EnsuresNonNullArguments()
{ {
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new FollowersClient(connection); var client = new FollowersClient(connection);
AssertEx.Throws<ArgumentNullException>(async () => await client.IsFollowing(null, "alfhenrik-test")); await AssertEx.Throws<ArgumentNullException>(() => client.IsFollowing(null, "alfhenrik-test"));
AssertEx.Throws<ArgumentNullException>(async () => await client.IsFollowing("alfhenrik", null)); await AssertEx.Throws<ArgumentNullException>(() => client.IsFollowing("alfhenrik", null));
AssertEx.Throws<ArgumentException>(async () => await client.IsFollowing("", "alfhenrik-text")); await AssertEx.Throws<ArgumentException>(() => client.IsFollowing("", "alfhenrik-text"));
AssertEx.Throws<ArgumentException>(async () => await client.IsFollowing("alfhenrik", "")); await AssertEx.Throws<ArgumentException>(() => client.IsFollowing("alfhenrik", ""));
} }
} }
@@ -233,7 +233,7 @@ namespace Octokit.Tests.Clients
apiConnection.Connection.Returns(connection); apiConnection.Connection.Returns(connection);
var client = new FollowersClient(apiConnection); var client = new FollowersClient(apiConnection);
AssertEx.Throws<ApiException>(async () => await client.Follow("alfhenrik")); await AssertEx.Throws<ApiException>(() => client.Follow("alfhenrik"));
} }
[Fact] [Fact]

View File

@@ -116,21 +116,16 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresArgumentsNotNull() public void EnsuresArgumentsNotNull()
{ {
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new IssuesClient(connection); var client = new IssuesClient(connection);
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.GetForRepository(null, "name", new RepositoryIssueRequest()));
client.GetForRepository(null, "name", new RepositoryIssueRequest())); Assert.Throws<ArgumentException>(() => client.GetForRepository("", "name", new RepositoryIssueRequest()));
AssertEx.Throws<ArgumentException>(async () => await Assert.Throws<ArgumentNullException>(() => client.GetForRepository("owner", null, new RepositoryIssueRequest()));
client.GetForRepository("", "name", new RepositoryIssueRequest())); Assert.Throws<ArgumentException>(() => client.GetForRepository("owner", "", new RepositoryIssueRequest()));
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.GetForRepository("owner", "name", null));
client.GetForRepository("owner", null, new RepositoryIssueRequest()));
AssertEx.Throws<ArgumentException>(async () => await
client.GetForRepository("owner", "", new RepositoryIssueRequest()));
AssertEx.Throws<ArgumentNullException>(async () => await
client.GetForRepository("owner", "name", null));
} }
} }
@@ -150,21 +145,16 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresArgumentsNotNull() public void EnsuresArgumentsNotNull()
{ {
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new IssuesClient(connection); var client = new IssuesClient(connection);
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", new NewIssue("title")));
client.Create(null, "name", new NewIssue("title"))); Assert.Throws<ArgumentException>(() => client.Create("", "name", new NewIssue("x")));
AssertEx.Throws<ArgumentException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, new NewIssue("x")));
client.Create("", "name", new NewIssue("x"))); Assert.Throws<ArgumentException>(() => client.Create("owner", "", new NewIssue("x")));
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
client.Create("owner", null, new NewIssue("x")));
AssertEx.Throws<ArgumentException>(async () => await
client.Create("owner", "", new NewIssue("x")));
AssertEx.Throws<ArgumentNullException>(async () => await
client.Create("owner", "name", null));
} }
} }
@@ -184,21 +174,16 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresArgumentsNotNull() public void EnsuresArgumentsNotNull()
{ {
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new IssuesClient(connection); var client = new IssuesClient(connection);
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Update(null, "name", 1, new IssueUpdate()));
client.Update(null, "name", 1, new IssueUpdate())); Assert.Throws<ArgumentException>(() => client.Update("", "name", 1, new IssueUpdate()));
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Update("owner", null, 1, new IssueUpdate()));
client.Update("", "name", 1, new IssueUpdate())); Assert.Throws<ArgumentException>(() => client.Update("owner", "", 1, new IssueUpdate()));
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Update("owner", "name", 1, null));
client.Update("owner", null, 1, new IssueUpdate()));
AssertEx.Throws<ArgumentNullException>(async () => await
client.Update("owner", "", 1, new IssueUpdate()));
AssertEx.Throws<ArgumentNullException>(async () => await
client.Update("owner", "name", 1, null));
} }
} }

View File

@@ -81,21 +81,16 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresArgumentsNotNull() public void EnsuresArgumentsNotNull()
{ {
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new MilestonesClient(connection); var client = new MilestonesClient(connection);
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", new NewMilestone("title")));
client.Create(null, "name", new NewMilestone("title"))); Assert.Throws<ArgumentException>(() => client.Create("", "name", new NewMilestone("x")));
AssertEx.Throws<ArgumentException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, new NewMilestone("x")));
client.Create("", "name", new NewMilestone("x"))); Assert.Throws<ArgumentException>(() => client.Create("owner", "", new NewMilestone("x")));
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
client.Create("owner", null, new NewMilestone("x")));
AssertEx.Throws<ArgumentException>(async () => await
client.Create("owner", "", new NewMilestone("x")));
AssertEx.Throws<ArgumentNullException>(async () => await
client.Create("owner", "name", null));
} }
} }
@@ -115,21 +110,16 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresArgumentsNotNull() public void EnsuresArgumentsNotNull()
{ {
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new MilestonesClient(connection); var client = new MilestonesClient(connection);
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", new NewMilestone("title")));
client.Create(null, "name", new NewMilestone("title"))); Assert.Throws<ArgumentException>(() => client.Create("", "name", new NewMilestone("x")));
AssertEx.Throws<ArgumentException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, new NewMilestone("x")));
client.Create("", "name", new NewMilestone("x"))); Assert.Throws<ArgumentException>(() => client.Create("owner", "", new NewMilestone("x")));
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
client.Create("owner", null, new NewMilestone("x")));
AssertEx.Throws<ArgumentException>(async () => await
client.Create("owner", "", new NewMilestone("x")));
AssertEx.Throws<ArgumentNullException>(async () => await
client.Create("owner", "name", null));
} }
} }
@@ -147,19 +137,15 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresArgumentsNotNull() public void EnsuresArgumentsNotNull()
{ {
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new MilestonesClient(connection); var client = new MilestonesClient(connection);
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Delete(null, "name", 42));
client.Delete(null, "name", 42)); Assert.Throws<ArgumentException>(() => client.Delete("", "name", 42));
AssertEx.Throws<ArgumentException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Delete("owner", null, 42));
client.Delete("", "name", 42)); Assert.Throws<ArgumentException>(() => client.Delete("owner", "", 42));
AssertEx.Throws<ArgumentNullException>(async () => await
client.Delete("owner", null, 42));
AssertEx.Throws<ArgumentException>(async () => await
client.Delete("owner", "", 42));
} }
} }

View File

@@ -45,8 +45,8 @@ namespace Octokit.Tests.Clients
{ {
var orgMembers = new OrganizationMembersClient(Substitute.For<IApiConnection>()); var orgMembers = new OrganizationMembersClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await orgMembers.GetAll(null)); Assert.Throws<ArgumentNullException>(() => orgMembers.GetAll(null));
AssertEx.Throws<ArgumentException>(async () => await orgMembers.GetAll("")); Assert.Throws<ArgumentException>(() => orgMembers.GetAll(""));
} }
} }
@@ -68,8 +68,8 @@ namespace Octokit.Tests.Clients
{ {
var orgMembers = new OrganizationMembersClient(Substitute.For<IApiConnection>()); var orgMembers = new OrganizationMembersClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await orgMembers.GetPublic(null)); Assert.Throws<ArgumentNullException>(() => orgMembers.GetPublic(null));
AssertEx.Throws<ArgumentException>(async () => await orgMembers.GetPublic("")); Assert.Throws<ArgumentException>(() => orgMembers.GetPublic(""));
} }
} }
@@ -107,7 +107,7 @@ namespace Octokit.Tests.Clients
apiConnection.Connection.Returns(connection); apiConnection.Connection.Returns(connection);
var client = new OrganizationMembersClient(apiConnection); var client = new OrganizationMembersClient(apiConnection);
AssertEx.Throws<ApiException>(async () => await client.CheckMember("org", "username")); await AssertEx.Throws<ApiException>(async () => await client.CheckMember("org", "username"));
} }
[Fact] [Fact]
@@ -155,7 +155,7 @@ namespace Octokit.Tests.Clients
apiConnection.Connection.Returns(connection); apiConnection.Connection.Returns(connection);
var client = new OrganizationMembersClient(apiConnection); var client = new OrganizationMembersClient(apiConnection);
AssertEx.Throws<ApiException>(async () => await client.CheckMemberPublic("org", "username")); await AssertEx.Throws<ApiException>(async () => await client.CheckMemberPublic("org", "username"));
} }
[Fact] [Fact]
@@ -227,7 +227,7 @@ namespace Octokit.Tests.Clients
apiConnection.Connection.Returns(connection); apiConnection.Connection.Returns(connection);
var client = new OrganizationMembersClient(apiConnection); var client = new OrganizationMembersClient(apiConnection);
AssertEx.Throws<ApiException>(async () => await client.Publicize("org", "username")); await AssertEx.Throws<ApiException>(async () => await client.Publicize("org", "username"));
} }
[Fact] [Fact]

View File

@@ -35,11 +35,11 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var orgs = new OrganizationsClient(Substitute.For<IApiConnection>()); var orgs = new OrganizationsClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await orgs.Get(null)); Assert.Throws<ArgumentNullException>(() => orgs.Get(null));
} }
} }
@@ -57,11 +57,11 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var orgs = new OrganizationsClient(Substitute.For<IApiConnection>()); var orgs = new OrganizationsClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await orgs.GetAll(null)); Assert.Throws<ArgumentNullException>(() => orgs.GetAll(null));
} }
} }

View File

@@ -34,6 +34,32 @@ namespace Octokit.Tests.Clients
} }
} }
public class TheGetReleaseMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new ReleasesClient(connection);
client.Get("fake", "repo", 1);
connection.Received().Get<Release>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/releases/1"),
null);
}
[Fact]
public void EnsuresNonNullArguments()
{
var releasesClient = new ReleasesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => releasesClient.Get(null, "name", 1));
Assert.Throws<ArgumentException>(() => releasesClient.Get("", "name", 1));
Assert.Throws<ArgumentNullException>(() => releasesClient.Get("owner", null, 1));
Assert.Throws<ArgumentException>(() => releasesClient.Get("owner", "", 1));
}
}
public class TheCreateReleaseMethod public class TheCreateReleaseMethod
{ {
[Fact] [Fact]
@@ -66,6 +92,85 @@ namespace Octokit.Tests.Clients
} }
} }
public class TheEditReleaseMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var releasesClient = new ReleasesClient(connection);
var data = new ReleaseUpdate("fake-tag");
releasesClient.EditRelease("fake", "repo", data);
connection.Received().Patch<Release>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/releases"), data);
}
[Fact]
public void EnsuresNonNullArguments()
{
var releasesClient = new ReleasesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => releasesClient.EditRelease(null, "name", new ReleaseUpdate("tag")));
Assert.Throws<ArgumentException>(() => releasesClient.EditRelease("", "name", new ReleaseUpdate("tag")));
Assert.Throws<ArgumentNullException>(() => releasesClient.EditRelease("owner", null, new ReleaseUpdate("tag")));
Assert.Throws<ArgumentException>(() => releasesClient.EditRelease("owner", "", new ReleaseUpdate("tag")));
Assert.Throws<ArgumentNullException>(() => releasesClient.EditRelease("owner", "name", null));
}
}
public class TheDeleteReleaseMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new ReleasesClient(connection);
client.DeleteRelease("fake", "repo", 1);
connection.Received().Delete(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/releases/1"));
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ReleasesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.DeleteRelease(null, "name", 1));
Assert.Throws<ArgumentException>(() => client.DeleteRelease("", "name", 1));
Assert.Throws<ArgumentNullException>(() => client.DeleteRelease("owner", null, 1));
Assert.Throws<ArgumentException>(() => client.DeleteRelease("owner", "", 1));
}
}
public class TheGetAssetsMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new ReleasesClient(connection);
client.GetAssets("fake", "repo", 1);
connection.Received().GetAll<ReleaseAsset>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/releases/1/assets"),
null,
"application/vnd.github.v3");
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ReleasesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.GetAssets(null, "name", 1));
Assert.Throws<ArgumentException>(() => client.GetAssets("", "name", 1));
Assert.Throws<ArgumentNullException>(() => client.GetAssets("owner", null, 1));
Assert.Throws<ArgumentException>(() => client.GetAssets("owner", "", 1));
}
}
public class TheUploadReleaseAssetMethod public class TheUploadReleaseAssetMethod
{ {
[Fact] [Fact]
@@ -97,5 +202,83 @@ namespace Octokit.Tests.Clients
await AssertEx.Throws<ArgumentNullException>(async () => await releasesClient.UploadAsset(release, null)); await AssertEx.Throws<ArgumentNullException>(async () => await releasesClient.UploadAsset(release, null));
} }
} }
public class TheGetAssetMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new ReleasesClient(connection);
client.GetAsset("fake", "repo", 1, 1);
connection.Received().Get<ReleaseAsset>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/releases/1/assets/1"), null);
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ReleasesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.GetAsset(null, "name", 1, 1));
Assert.Throws<ArgumentException>(() => client.GetAsset("", "name", 1, 1));
Assert.Throws<ArgumentNullException>(() => client.GetAsset("owner", null, 1, 1));
Assert.Throws<ArgumentException>(() => client.GetAsset("owner", "", 1, 1));
}
}
public class TheEditAssetMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new ReleasesClient(connection);
var data = new ReleaseAssetUpdate("asset");
client.EditAsset("fake", "repo", 1, 1, data);
connection.Received().Patch<ReleaseAsset>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/releases/1/assets/1"),
data);
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ReleasesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.EditAsset(null, "name", 1, 1, new ReleaseAssetUpdate("name")));
Assert.Throws<ArgumentException>(() => client.EditAsset("", "name", 1, 1, new ReleaseAssetUpdate("name")));
Assert.Throws<ArgumentNullException>(() => client.EditAsset("owner", null, 1, 1, new ReleaseAssetUpdate("name")));
Assert.Throws<ArgumentException>(() => client.EditAsset("owner", "", 1, 1, new ReleaseAssetUpdate("name")));
Assert.Throws<ArgumentNullException>(() => client.EditAsset("owner", "name", 1, 1, null));
}
}
public class TheDeleteAssetMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new ReleasesClient(connection);
client.DeleteAsset("fake", "repo", 1);
connection.Received().Delete(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/releases/assets/1"));
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ReleasesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.DeleteAsset(null, "name", 1));
Assert.Throws<ArgumentException>(() => client.DeleteAsset("", "name", 1));
Assert.Throws<ArgumentNullException>(() => client.DeleteAsset("owner", null, 1));
Assert.Throws<ArgumentException>(() => client.DeleteAsset("owner", "", 1));
}
}
} }
} }

View File

@@ -37,14 +37,14 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var client = new RepoCollaboratorsClient(Substitute.For<IApiConnection>()); var client = new RepoCollaboratorsClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await client.GetAll(null,"test")); Assert.Throws<ArgumentNullException>(() => client.GetAll(null,"test"));
AssertEx.Throws<ArgumentNullException>(async () => await client.GetAll("", "test")); Assert.Throws<ArgumentException>(() => client.GetAll("", "test"));
AssertEx.Throws<ArgumentNullException>(async () => await client.GetAll("owner", null)); Assert.Throws<ArgumentNullException>(() => client.GetAll("owner", null));
AssertEx.Throws<ArgumentNullException>(async () => await client.GetAll("owner", "")); Assert.Throws<ArgumentException>(() => client.GetAll("owner", ""));
} }
} }
@@ -81,7 +81,7 @@ namespace Octokit.Tests.Clients
apiConnection.Connection.Returns(connection); apiConnection.Connection.Returns(connection);
var client = new AssigneesClient(apiConnection); var client = new AssigneesClient(apiConnection);
AssertEx.Throws<ApiException>(async () => await client.CheckAssignee("foo", "bar", "cody")); await AssertEx.Throws<ApiException>(() => client.CheckAssignee("foo", "bar", "cody"));
} }
[Fact] [Fact]
@@ -89,12 +89,12 @@ namespace Octokit.Tests.Clients
{ {
var client = new RepoCollaboratorsClient(Substitute.For<IApiConnection>()); var client = new RepoCollaboratorsClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await client.IsCollaborator(null, "test", "user1")); await AssertEx.Throws<ArgumentNullException>(() => client.IsCollaborator(null, "test", "user1"));
AssertEx.Throws<ArgumentNullException>(async () => await client.IsCollaborator("", "test", "user1")); await AssertEx.Throws<ArgumentException>(() => client.IsCollaborator("", "test", "user1"));
AssertEx.Throws<ArgumentNullException>(async () => await client.IsCollaborator("owner", null, "user1")); await AssertEx.Throws<ArgumentNullException>(() => client.IsCollaborator("owner", null, "user1"));
AssertEx.Throws<ArgumentNullException>(async () => await client.IsCollaborator("owner", "", "user1")); await AssertEx.Throws<ArgumentException>(() => client.IsCollaborator("owner", "", "user1"));
AssertEx.Throws<ArgumentNullException>(async () => await client.IsCollaborator("owner", "test", "")); await AssertEx.Throws<ArgumentException>(() => client.IsCollaborator("owner", "test", ""));
AssertEx.Throws<ArgumentNullException>(async () => await client.IsCollaborator("owner", "test", null)); await AssertEx.Throws<ArgumentNullException>(() => client.IsCollaborator("owner", "test", null));
} }
} }
@@ -111,16 +111,16 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var client = new RepoCollaboratorsClient(Substitute.For<IApiConnection>()); var client = new RepoCollaboratorsClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await client.Add(null, "test","user1")); Assert.Throws<ArgumentNullException>(() => client.Add(null, "test","user1"));
AssertEx.Throws<ArgumentNullException>(async () => await client.Add("", "test", "user1")); Assert.Throws<ArgumentException>(() => client.Add("", "test", "user1"));
AssertEx.Throws<ArgumentNullException>(async () => await client.Add("owner", null, "user1")); Assert.Throws<ArgumentNullException>(() => client.Add("owner", null, "user1"));
AssertEx.Throws<ArgumentNullException>(async () => await client.Add("owner", "", "user1")); Assert.Throws<ArgumentException>(() => client.Add("owner", "", "user1"));
AssertEx.Throws<ArgumentNullException>(async () => await client.Add("owner", "test", "")); Assert.Throws<ArgumentException>(() => client.Add("owner", "test", ""));
AssertEx.Throws<ArgumentNullException>(async () => await client.Add("owner", "test", null)); Assert.Throws<ArgumentNullException>(() => client.Add("owner", "test", null));
} }
} }
@@ -137,16 +137,16 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var client = new RepoCollaboratorsClient(Substitute.For<IApiConnection>()); var client = new RepoCollaboratorsClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await client.Delete(null, "test", "user1")); Assert.Throws<ArgumentNullException>(() => client.Delete(null, "test", "user1"));
AssertEx.Throws<ArgumentNullException>(async () => await client.Delete("", "test", "user1")); Assert.Throws<ArgumentException>(() => client.Delete("", "test", "user1"));
AssertEx.Throws<ArgumentNullException>(async () => await client.Delete("owner", null, "user1")); Assert.Throws<ArgumentNullException>(() => client.Delete("owner", null, "user1"));
AssertEx.Throws<ArgumentNullException>(async () => await client.Delete("owner", "", "user1")); Assert.Throws<ArgumentException>(() => client.Delete("owner", "", "user1"));
AssertEx.Throws<ArgumentNullException>(async () => await client.Delete("owner", "test", "")); Assert.Throws<ArgumentException>(() => client.Delete("owner", "test", ""));
AssertEx.Throws<ArgumentNullException>(async () => await client.Delete("owner", "test", null)); Assert.Throws<ArgumentNullException>(() => client.Delete("owner", "test", null));
} }
} }
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using NSubstitute; using NSubstitute;
@@ -171,11 +172,11 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var reposEndpoint = new RepositoriesClient(Substitute.For<IApiConnection>()); var reposEndpoint = new RepositoriesClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await reposEndpoint.GetAllForUser(null)); Assert.Throws<ArgumentNullException>(() => reposEndpoint.GetAllForUser(null));
} }
} }
@@ -198,7 +199,7 @@ namespace Octokit.Tests.Clients
{ {
var reposEndpoint = new RepositoriesClient(Substitute.For<IApiConnection>()); var reposEndpoint = new RepositoriesClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await reposEndpoint.GetAllForOrg(null)); Assert.Throws<ArgumentNullException>(() => reposEndpoint.GetAllForOrg(null));
} }
} }
@@ -263,6 +264,178 @@ namespace Octokit.Tests.Clients
connection.Received() connection.Received()
.GetAll<Branch>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/name/branches")); .GetAll<Branch>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/name/branches"));
} }
[Fact]
public void EnsuresArguments()
{
var client = new RepositoriesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.GetAllBranches(null, "repo"));
Assert.Throws<ArgumentNullException>(() => client.GetAllBranches("owner", null));
Assert.Throws<ArgumentException>(() => client.GetAllBranches("", "repo"));
Assert.Throws<ArgumentException>(() => client.GetAllBranches("owner", ""));
}
}
public class TheGetAllContributorsMethod
{
[Fact]
public void GetsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoriesClient(connection);
client.GetAllContributors("owner", "name");
connection.Received()
.GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/name/contributors"), Arg.Any<IDictionary<string, string>>());
}
[Fact]
public void EnsuresArguments()
{
var client = new RepositoriesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.GetAllContributors(null, "repo"));
Assert.Throws<ArgumentNullException>(() => client.GetAllContributors("owner", null));
Assert.Throws<ArgumentException>(() => client.GetAllContributors("", "repo"));
Assert.Throws<ArgumentException>(() => client.GetAllContributors("owner", ""));
}
}
public class TheGetAllLanguagesMethod
{
[Fact]
public void GetsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoriesClient(connection);
client.GetAllLanguages("owner", "name");
connection.Received()
.Get<IDictionary<string, long>>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/name/languages"), null);
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new RepositoriesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.GetAllLanguages(null, "repo"));
Assert.Throws<ArgumentNullException>(() => client.GetAllLanguages("owner", null));
Assert.Throws<ArgumentException>(() => client.GetAllLanguages("", "repo"));
Assert.Throws<ArgumentException>(() => client.GetAllLanguages("owner", ""));
}
}
public class TheGetAllTeamsMethod
{
[Fact]
public void GetsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoriesClient(connection);
client.GetAllTeams("owner", "name");
connection.Received()
.GetAll<Team>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/name/teams"));
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new RepositoriesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.GetAllTeams(null, "repo"));
Assert.Throws<ArgumentNullException>(() => client.GetAllTeams("owner", null));
Assert.Throws<ArgumentException>(() => client.GetAllTeams("", "repo"));
Assert.Throws<ArgumentException>(() => client.GetAllTeams("owner", ""));
}
}
public class TheGetAllTagsMethod
{
[Fact]
public void GetsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoriesClient(connection);
client.GetAllTags("owner", "name");
connection.Received()
.GetAll<RepositoryTag>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/name/tags"));
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new RepositoriesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.GetAllTags(null, "repo"));
Assert.Throws<ArgumentNullException>(() => client.GetAllTags("owner", null));
Assert.Throws<ArgumentException>(() => client.GetAllTags("", "repo"));
Assert.Throws<ArgumentException>(() => client.GetAllTags("owner", ""));
}
}
public class TheGetBranchMethod
{
[Fact]
public void GetsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoriesClient(connection);
client.GetBranch("owner", "repo", "branch");
connection.Received()
.Get<Branch>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/repo/branches/branch"), null);
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new RepositoriesClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.GetBranch(null, "repo", "branch"));
Assert.Throws<ArgumentNullException>(() => client.GetBranch("owner", null, "branch"));
Assert.Throws<ArgumentNullException>(() => client.GetBranch("owner", "repo", null));
Assert.Throws<ArgumentException>(() => client.GetBranch("", "repo", "branch"));
Assert.Throws<ArgumentException>(() => client.GetBranch("owner", "", "branch"));
Assert.Throws<ArgumentException>(() => client.GetBranch("owner", "repo", ""));
}
}
public class TheEditMethod
{
[Fact]
public void PatchesCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new RepositoriesClient(connection);
var update = new RepositoryUpdate();
client.Edit("owner", "repo", update);
connection.Received()
.Patch<Repository>(Arg.Is<Uri>(u => u.ToString() == "repos/owner/repo"), Arg.Any<RepositoryUpdate>());
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new RepositoriesClient(Substitute.For<IApiConnection>());
var update = new RepositoryUpdate();
Assert.Throws<ArgumentNullException>(() => client.Edit(null, "repo", update));
Assert.Throws<ArgumentNullException>(() => client.Edit("owner", null, update));
Assert.Throws<ArgumentNullException>(() => client.Edit("owner", "repo", null));
Assert.Throws<ArgumentException>(() => client.Edit("", "repo", update));
Assert.Throws<ArgumentException>(() => client.Edit("owner", "", update));
}
} }
} }
} }

View File

@@ -34,10 +34,297 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var client = new SearchClient(Substitute.For<IApiConnection>()); var client = new SearchClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await client.SearchUsers(null)); Assert.Throws<ArgumentNullException>(() => client.SearchUsers(null));
}
[Fact]
public void TestingTheTermParameter()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github"));
}
[Fact]
public void TestingTheAccountTypeQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.AccountType = AccountType.User;
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+type:User"));
}
[Fact]
public void TestingTheAccountTypeQualifier_Org()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.AccountType = AccountType.Org;
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+type:Org"));
}
[Fact]
public void TestingTheInQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
//get users where the fullname contains 'github'
var request = new SearchUsersRequest("github");
request.In = new[] { UserInQualifier.Fullname };
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+in:Fullname"));
}
[Fact]
public void TestingTheInQualifier_Email()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.In = new[] { UserInQualifier.Email };
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+in:Email"));
}
[Fact]
public void TestingTheInQualifier_Username()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.In = new[] { UserInQualifier.Username };
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+in:Username"));
}
[Fact]
public void TestingTheInQualifier_Multiple()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.In = new[] { UserInQualifier.Username, UserInQualifier.Fullname, UserInQualifier.Email };
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+in:Username,Fullname,Email"));
}
[Fact]
public void TestingTheReposQualifier_GreaterThan()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Repositories = Range.GreaterThan(5);
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+repos:>5"));
}
[Fact]
public void TestingTheReposQualifier_GreaterThanOrEqualTo()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Repositories = Range.GreaterThanOrEquals(5);
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+repos:>=5"));
}
[Fact]
public void TestingTheReposQualifier_LessThanOrEqualTo()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Repositories = Range.LessThanOrEquals(5);
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+repos:<=5"));
}
[Fact]
public void TestingTheReposQualifier_LessThan()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Repositories = Range.LessThan(5);
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+repos:<5"));
}
[Fact]
public void TestingTheLocationQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Location = "San Francisco";
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+location:San Francisco"));
}
[Fact]
public void TestingTheLanguageQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
//get users who have mostly repos where language is Ruby
var request = new SearchUsersRequest("github");
request.Language = Language.Ruby;
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+language:Ruby"));
}
[Fact]
public void TestingTheCreatedQualifier_GreaterThan()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Created = DateRange.GreaterThan(new DateTime(2014, 1, 1));
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+created:>2014-01-01"));
}
[Fact]
public void TestingTheCreatedQualifier_GreaterThanOrEqualTo()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Created = DateRange.GreaterThanOrEquals(new DateTime(2014, 1, 1));
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+created:>=2014-01-01"));
}
[Fact]
public void TestingTheCreatedQualifier_LessThanOrEqualTo()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Created = DateRange.LessThanOrEquals(new DateTime(2014, 1, 1));
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+created:<=2014-01-01"));
}
[Fact]
public void TestingTheCreatedQualifier_LessThan()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Created = DateRange.LessThan(new DateTime(2014, 1, 1));
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+created:<2014-01-01"));
}
[Fact]
public void TestingTheFollowersQualifier_GreaterThan()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Followers = Range.GreaterThan(1);
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+followers:>1"));
}
[Fact]
public void TestingTheFollowersQualifier_GreaterThanOrEqualTo()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Followers = Range.GreaterThanOrEquals(1);
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+followers:>=1"));
}
[Fact]
public void TestingTheFollowersQualifier_LessThan()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Followers = Range.LessThan(1);
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+followers:<1"));
}
[Fact]
public void TestingTheFollowersQualifier_LessThanOrEqualTo()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Followers = Range.LessThanOrEquals(1);
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+followers:<=1"));
}
[Fact]
public void TestingTheFollowersQualifier_Range()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchUsersRequest("github");
request.Followers = new Range(1, 1000);
client.SearchUsers(request);
connection.Received().GetAll<User>(
Arg.Is<Uri>(u => u.ToString() == "search/users"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "github+followers:1..1000"));
} }
} }
@@ -53,10 +340,10 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var client = new SearchClient(Substitute.For<IApiConnection>()); var client = new SearchClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await client.SearchRepo(null)); Assert.Throws<ArgumentNullException>(() => client.SearchRepo(null));
} }
[Fact] [Fact]
@@ -192,7 +479,7 @@ namespace Octokit.Tests.Clients
//get repos where the Description contains rails and user/org is 'github' //get repos where the Description contains rails and user/org is 'github'
var request = new SearchRepositoriesRequest("rails"); var request = new SearchRepositoriesRequest("rails");
request.Sort = RepoSearchSort.Forks; request.Sort = RepoSearchSort.Forks;
client.SearchRepo(request); client.SearchRepo(request);
connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>()); connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
@@ -211,10 +498,10 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var client = new SearchClient(Substitute.For<IApiConnection>()); var client = new SearchClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await client.SearchIssues(null)); Assert.Throws<ArgumentNullException>(() => client.SearchIssues(null));
} }
[Fact] [Fact]
@@ -227,7 +514,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "pub")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "pub"));
} }
@@ -242,8 +529,8 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => Arg.Is<Dictionary<string, string>>(d =>
d["sort"] == "comments")); d["sort"] == "comments"));
} }
@@ -275,8 +562,8 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => Arg.Is<Dictionary<string, string>>(d =>
d["order"] == "desc")); d["order"] == "desc"));
} }
@@ -291,8 +578,8 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u=>u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d=>d["q"] == "something+in:comment")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+in:comment"));
} }
[Fact] [Fact]
@@ -306,7 +593,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+in:body,title")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+in:body,title"));
} }
@@ -321,7 +608,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+type:issue")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+type:issue"));
} }
@@ -336,7 +623,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+type:pr")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+type:pr"));
} }
@@ -351,7 +638,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+author:alfhenrik")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+author:alfhenrik"));
} }
@@ -366,7 +653,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+assignee:alfhenrik")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+assignee:alfhenrik"));
} }
@@ -381,7 +668,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+mentions:alfhenrik")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+mentions:alfhenrik"));
} }
@@ -396,7 +683,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+commenter:alfhenrik")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+commenter:alfhenrik"));
} }
@@ -411,7 +698,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+involves:alfhenrik")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+involves:alfhenrik"));
} }
@@ -426,7 +713,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+state:Open")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+state:Open"));
} }
@@ -441,7 +728,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+state:Closed")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+state:Closed"));
} }
@@ -456,7 +743,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+label:bug")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+label:bug"));
} }
@@ -471,7 +758,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+label:bug+label:feature")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+label:bug+label:feature"));
} }
@@ -486,10 +773,10 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+language:CSharp")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+language:CSharp"));
} }
[Fact] [Fact]
public void TestingTheCreatedQualifier_GreaterThan() public void TestingTheCreatedQualifier_GreaterThan()
{ {
@@ -501,7 +788,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+created:>2014-01-01")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+created:>2014-01-01"));
} }
@@ -516,7 +803,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+created:>=2014-01-01")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+created:>=2014-01-01"));
} }
@@ -531,7 +818,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+created:<2014-01-01")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+created:<2014-01-01"));
} }
@@ -546,7 +833,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+created:<=2014-01-01")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+created:<=2014-01-01"));
} }
@@ -561,7 +848,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+updated:>2014-01-01")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+updated:>2014-01-01"));
} }
@@ -576,7 +863,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+updated:>=2014-01-01")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+updated:>=2014-01-01"));
} }
@@ -591,7 +878,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+updated:<2014-01-01")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+updated:<2014-01-01"));
} }
@@ -606,7 +893,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+updated:<=2014-01-01")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+updated:<=2014-01-01"));
} }
@@ -621,7 +908,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+comments:>10")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+comments:>10"));
} }
@@ -636,7 +923,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+comments:>=10")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+comments:>=10"));
} }
@@ -651,7 +938,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+comments:<10")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+comments:<10"));
} }
@@ -666,7 +953,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+comments:<=10")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+comments:<=10"));
} }
@@ -681,7 +968,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+comments:10..20")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+comments:10..20"));
} }
@@ -696,7 +983,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+user:alfhenrik")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+user:alfhenrik"));
} }
@@ -711,7 +998,7 @@ namespace Octokit.Tests.Clients
client.SearchIssues(request); client.SearchIssues(request);
connection.Received().GetAll<Issue>( connection.Received().GetAll<Issue>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+repo:octokit.net")); Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+repo:octokit.net"));
} }
@@ -743,15 +1030,15 @@ namespace Octokit.Tests.Clients
var client = new SearchClient(connection); var client = new SearchClient(connection);
client.SearchCode(new SearchCodeRequest("something")); client.SearchCode(new SearchCodeRequest("something"));
connection.Received().GetAll<SearchCode>( connection.Received().GetAll<SearchCode>(
Arg.Is<Uri>(u => u.ToString() == "search/code"), Arg.Is<Uri>(u => u.ToString() == "search/code"),
Arg.Any<Dictionary<string, string>>()); Arg.Any<Dictionary<string, string>>());
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var client = new SearchClient(Substitute.For<IApiConnection>()); var client = new SearchClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await client.SearchCode(null)); Assert.Throws<ArgumentNullException>(() => client.SearchCode(null));
} }
[Fact] [Fact]

View File

@@ -0,0 +1,171 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using NSubstitute;
using Octokit.Tests.Helpers;
using Xunit;
namespace Octokit.Tests.Clients
{
public class StatisticsClientTests
{
public class TheConstructor
{
[Fact]
public void DoesThrowOnBadArguments()
{
Assert.Throws<ArgumentNullException>(() => new StatisticsClient(null));
}
}
public class TheGetContributorsMethod
{
[Fact]
public void RequestsCorrectUrl()
{
var expectedEndPoint = new Uri("/repos/username/repositoryName/stats/contributors", UriKind.Relative);
var client = Substitute.For<IApiConnection>();
var statisticsClient = new StatisticsClient(client);
statisticsClient.GetContributors("username","repositoryName");
client.Received().GetQueuedOperation<IEnumerable<Contributor>>(expectedEndPoint,Args.CancellationToken);
}
[Fact]
public async Task ThrowsIfGivenNullOwner()
{
var statisticsClient = new StatisticsClient(Substitute.For<IApiConnection>());
await AssertEx.Throws<ArgumentNullException>(() => statisticsClient.GetContributors(null,"repositoryName"));
}
[Fact]
public async Task ThrowsIfGivenNullRepositoryName()
{
var statisticsClient = new StatisticsClient(Substitute.For<IApiConnection>());
await AssertEx.Throws<ArgumentNullException>(() => statisticsClient.GetContributors("owner", null));
}
}
public class TheGetCommitActivityForTheLastYearMethod
{
[Fact]
public void RequestsCorrectUrl()
{
var expectedEndPoint = new Uri("/repos/username/repositoryName/stats/commit_activity", UriKind.Relative);
var client = Substitute.For<IApiConnection>();
var statisticsClient = new StatisticsClient(client);
statisticsClient.GetCommitActivity("username", "repositoryName");
client.Received().GetQueuedOperation<IEnumerable<WeeklyCommitActivity>>(expectedEndPoint, Args.CancellationToken);
}
[Fact]
public async Task ThrowsIfGivenNullOwner()
{
var statisticsClient = new StatisticsClient(Substitute.For<IApiConnection>());
await AssertEx.Throws<ArgumentNullException>(() => statisticsClient.GetCommitActivity(null, "repositoryName"));
}
[Fact]
public async Task ThrowsIfGivenNullRepositoryName()
{
var statisticsClient = new StatisticsClient(Substitute.For<IApiConnection>());
await AssertEx.Throws<ArgumentNullException>(() => statisticsClient.GetCommitActivity("owner", null));
}
}
public class TheGetAdditionsAndDeletionsPerWeekMethod
{
[Fact]
public void RequestsCorrectUrl()
{
var expectedEndPoint = new Uri("/repos/username/repositoryName/stats/code_frequency", UriKind.Relative);
var client = Substitute.For<IApiConnection>();
var statisticsClient = new StatisticsClient(client);
statisticsClient.GetCodeFrequency("username", "repositoryName");
client.Received().GetQueuedOperation<IEnumerable<long[]>>(expectedEndPoint, Args.CancellationToken);
}
[Fact]
public async Task ThrowsIfGivenNullOwner()
{
var statisticsClient = new StatisticsClient(Substitute.For<IApiConnection>());
await AssertEx.Throws<ArgumentNullException>(() => statisticsClient.GetCodeFrequency(null, "repositoryName"));
}
[Fact]
public async Task ThrowsIfGivenNullRepositoryName()
{
var statisticsClient = new StatisticsClient(Substitute.For<IApiConnection>());
await AssertEx.Throws<ArgumentNullException>(() => statisticsClient.GetCodeFrequency("owner", null));
}
}
public class TheGetWeeklyCommitCountsMethod
{
[Fact]
public void RequestsCorrectUrl()
{
var expectedEndPoint = new Uri("/repos/username/repositoryName/stats/participation", UriKind.Relative);
var client = Substitute.For<IApiConnection>();
var statisticsClient = new StatisticsClient(client);
statisticsClient.GetParticipation("username", "repositoryName");
client.Received().GetQueuedOperation<Participation>(expectedEndPoint, Args.CancellationToken);
}
[Fact]
public async Task ThrowsIfGivenNullOwner()
{
var statisticsClient = new StatisticsClient(Substitute.For<IApiConnection>());
await AssertEx.Throws<ArgumentNullException>(() => statisticsClient.GetParticipation(null, "repositoryName"));
}
[Fact]
public async Task ThrowsIfGivenNullRepositoryName()
{
var statisticsClient = new StatisticsClient(Substitute.For<IApiConnection>());
await AssertEx.Throws<ArgumentNullException>(() => statisticsClient.GetParticipation("owner", null));
}
}
public class TheGetHourlyCommitCountsMethod
{
[Fact]
public void RequestsCorrectUrl()
{
var expectedEndPoint = new Uri("/repos/username/repositoryName/stats/punch_card", UriKind.Relative);
var client = Substitute.For<IApiConnection>();
var statisticsClient = new StatisticsClient(client);
statisticsClient.GetPunchCard("username", "repositoryName");
client.Received().GetQueuedOperation<IEnumerable<int[]>>(expectedEndPoint, Args.CancellationToken);
}
[Fact]
public async Task ThrowsIfGivenNullOwner()
{
var statisticsClient = new StatisticsClient(Substitute.For<IApiConnection>());
await AssertEx.Throws<ArgumentNullException>(() => statisticsClient.GetPunchCard(null, "repositoryName"));
}
[Fact]
public async Task ThrowsIfGivenNullRepositoryName()
{
var statisticsClient = new StatisticsClient(Substitute.For<IApiConnection>());
await AssertEx.Throws<ArgumentNullException>(() => statisticsClient.GetPunchCard("owner", null));
}
}
}
}

View File

@@ -35,11 +35,11 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var teams = new TeamsClient(Substitute.For<IApiConnection>()); var teams = new TeamsClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await teams.GetAllTeams(null)); Assert.Throws<ArgumentNullException>(() => teams.GetAllTeams(null));
} }
} }
@@ -58,15 +58,15 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new TeamsClient(connection); var client = new TeamsClient(connection);
var team = new NewTeam("superstars");
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.CreateTeam(null, team));
client.CreateTeam("", new NewTeam("superstars"))); Assert.Throws<ArgumentException>(() => client.CreateTeam("", team));
AssertEx.Throws<ArgumentException>(async () => await Assert.Throws<ArgumentNullException>(() => client.CreateTeam("name", null));
client.CreateTeam("name", null));
} }
} }
@@ -85,13 +85,12 @@ namespace Octokit.Tests.Clients
} }
[Fact] [Fact]
public async Task EnsuresNonNullArguments() public void EnsuresNonNullArguments()
{ {
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new TeamsClient(connection); var client = new TeamsClient(connection);
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.UpdateTeam(1, null));
client.UpdateTeam(1, null));
} }
} }

View File

@@ -0,0 +1,66 @@
using NSubstitute;
using Octokit.Tests.Helpers;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit;
namespace Octokit.Tests.Clients
{
public class UserEmailsClientTests
{
public class TheGetAllMethod
{
[Fact]
public void GetsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new UserEmailsClient(connection);
client.GetAll();
connection.Received(1)
.GetAll<EmailAddress>(Arg.Is<Uri>(u => u.ToString() == "user/emails"));
}
}
public class TheAddMethod
{
[Fact]
public void PostsToCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new UserEmailsClient(connection);
client.Add("octocat@github.com");
connection.Received(1)
.Post<IReadOnlyList<string>>(Arg.Is<Uri>(u => u.ToString() == "user/emails"), Arg.Any<string[]>());
}
[Fact]
public void EnsuresNonNullArgument()
{
var client = new UserEmailsClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentNullException>(() => client.Add(null));
}
[Fact]
public void EnsuresNoNullEmails()
{
var client = new UserEmailsClient(Substitute.For<IApiConnection>());
Assert.Throws<ArgumentException>(() => client.Add("octokit@github.com", null));
}
}
public class TheCtor
{
[Fact]
public void EnsuresArguments()
{
Assert.Throws<ArgumentNullException>(
() => new UserEmailsClient(null));
}
}
}
}

View File

@@ -90,20 +90,5 @@ namespace Octokit.Tests.Clients
await AssertEx.Throws<ArgumentNullException>(() => userEndpoint.Update(null)); await AssertEx.Throws<ArgumentNullException>(() => userEndpoint.Update(null));
} }
} }
public class TheGetEmailsMethod
{
[Fact]
public void SendsUpdateToCorrectUrl()
{
var endpoint = new Uri("user/emails", UriKind.Relative);
var client = Substitute.For<IApiConnection>();
var usersClient = new UsersClient(client);
usersClient.GetEmails();
client.Received().GetAll<EmailAddress>(endpoint, null);
}
}
} }
} }

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using NSubstitute; using NSubstitute;
using Octokit.Internal; using Octokit.Internal;
@@ -51,5 +52,10 @@ namespace Octokit.Tests
{ {
get { return Arg.Is<Dictionary<string, string>>(d => d.Count == 0); } get { return Arg.Is<Dictionary<string, string>>(d => d.Count == 0); }
} }
public static CancellationToken CancellationToken
{
get { return Arg.Any<CancellationToken>(); }
}
} }
} }

View File

@@ -1,11 +1,38 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xunit; using Xunit;
using Xunit.Sdk;
namespace Octokit.Tests.Helpers namespace Octokit.Tests.Helpers
{ {
public static class AssertEx public static class AssertEx
{ {
public static void Empty<T>(IEnumerable<T> actual, string message)
{
var empty = Enumerable.Empty<T>();
WithMessage(() => Assert.Equal(empty, actual.ToArray()), message);
}
public static void WithMessage(Action assert, string message)
{
try
{
assert();
}
catch(AssertException ex)
{
throw new Exception(message, ex);
}
}
public static void HasAttribute<TAttribute>(MemberInfo memberInfo, bool inherit = false) where TAttribute : Attribute
{
Assert.True(memberInfo.IsDefined(typeof(TAttribute), inherit), memberInfo.ToString() + Environment.NewLine);
}
public async static Task<T> Throws<T>(Func<Task> testCode) where T : Exception public async static Task<T> Throws<T>(Func<Task> testCode) where T : Exception
{ {
try try
@@ -21,5 +48,15 @@ namespace Octokit.Tests.Helpers
// Assert.Throws above will always throw. // Assert.Throws above will always throw.
return null; return null;
} }
static readonly string[] whitespaceArguments = { " ", "\t", "\n", "\n\r", " " };
public static async Task ThrowsWhenGivenWhitespaceArgument(Func<string, Task> action)
{
foreach (var argument in whitespaceArguments)
{
await Throws<ArgumentException>(async () => await action(argument));
}
}
} }
} }

View File

@@ -2,6 +2,7 @@
using System.Net; using System.Net;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using NSubstitute; using NSubstitute;
using Octokit.Internal; using Octokit.Internal;
@@ -267,6 +268,110 @@ namespace Octokit.Tests.Http
} }
} }
public class TheGetQueuedOperationMethod
{
[Fact]
public async Task MakesGetRequest()
{
var queuedOperationUrl = new Uri("anything", UriKind.Relative);
const HttpStatusCode statusCode = HttpStatusCode.OK;
IResponse<object> response = new ApiResponse<object> { BodyAsObject = new object(), StatusCode = statusCode };
var connection = Substitute.For<IConnection>();
connection.GetAsync<object>(queuedOperationUrl,Args.CancellationToken).Returns(Task.FromResult(response));
var apiConnection = new ApiConnection(connection);
await apiConnection.GetQueuedOperation<object>(queuedOperationUrl,CancellationToken.None);
connection.Received().GetAsync<object>(queuedOperationUrl, Args.CancellationToken);
}
[Fact]
public async Task WhenGetReturnsNotOkOrAcceptedApiExceptionIsThrown()
{
var queuedOperationUrl = new Uri("anything", UriKind.Relative);
const HttpStatusCode statusCode = HttpStatusCode.PartialContent;
IResponse<object> response = new ApiResponse<object> { BodyAsObject = new object(), StatusCode = statusCode };
var connection = Substitute.For<IConnection>();
connection.GetAsync<object>(queuedOperationUrl, Args.CancellationToken).Returns(Task.FromResult(response));
var apiConnection = new ApiConnection(connection);
await AssertEx.Throws<ApiException>(async () => await apiConnection.GetQueuedOperation<object>(queuedOperationUrl, Args.CancellationToken));
}
[Fact]
public async Task WhenGetReturnsOkThenBodyAsObjectIsReturned()
{
var queuedOperationUrl = new Uri("anything", UriKind.Relative);
var result = new object();
const HttpStatusCode statusCode = HttpStatusCode.OK;
IResponse<object> response = new ApiResponse<object> { BodyAsObject = result, StatusCode = statusCode };
var connection = Substitute.For<IConnection>();
connection.GetAsync<object>(queuedOperationUrl, Args.CancellationToken).Returns(Task.FromResult(response));
var apiConnection = new ApiConnection(connection);
var actualResult = await apiConnection.GetQueuedOperation<object>(queuedOperationUrl, Args.CancellationToken);
Assert.Same(actualResult,result);
}
[Fact]
public async Task GetIsRepeatedUntilHttpStatusCodeOkIsReturned()
{
var queuedOperationUrl = new Uri("anything", UriKind.Relative);
var result = new object();
IResponse<object> firstResponse = new ApiResponse<object> { BodyAsObject = result, StatusCode = HttpStatusCode.Accepted };
IResponse<object> completedResponse = new ApiResponse<object> { BodyAsObject = result, StatusCode = HttpStatusCode.OK };
var connection = Substitute.For<IConnection>();
connection.GetAsync<object>(queuedOperationUrl, Args.CancellationToken)
.Returns(x => Task.FromResult(firstResponse),
x => Task.FromResult(firstResponse),
x => Task.FromResult(completedResponse));
var apiConnection = new ApiConnection(connection);
await apiConnection.GetQueuedOperation<object>(queuedOperationUrl, CancellationToken.None);
connection.Received(3).GetAsync<object>(queuedOperationUrl, Args.CancellationToken);
}
public async Task CanCancelQueuedOperation()
{
var queuedOperationUrl = new Uri("anything", UriKind.Relative);
var result = new object();
IResponse<object> accepted = new ApiResponse<object> { BodyAsObject = result, StatusCode = HttpStatusCode.Accepted };
var connection = Substitute.For<IConnection>();
connection.GetAsync<object>(queuedOperationUrl, Args.CancellationToken).Returns(x => Task.FromResult(accepted));
var apiConnection = new ApiConnection(connection);
var cancellationTokenSource = new CancellationTokenSource();
cancellationTokenSource.CancelAfter(100);
var canceled = false;
var operationResult = await apiConnection.GetQueuedOperation<object>(queuedOperationUrl, cancellationTokenSource.Token)
.ContinueWith(task =>
{
canceled = task.IsCanceled;
return task;
}, TaskContinuationOptions.OnlyOnCanceled)
.ContinueWith(task => task, TaskContinuationOptions.OnlyOnFaulted);
Assert.True(canceled);
Assert.Null(operationResult);
}
[Fact]
public async Task EnsuresArgumentNotNull()
{
var connection = new ApiConnection(Substitute.For<IConnection>());
await AssertEx.Throws<ArgumentNullException>(async () => await connection.GetQueuedOperation<object>(null, CancellationToken.None));
}
}
public class TheCtor public class TheCtor
{ {
[Fact] [Fact]

View File

@@ -25,7 +25,7 @@ namespace Octokit.Tests.Http
{ {
var httpClient = Substitute.For<IHttpClient>(); var httpClient = Substitute.For<IHttpClient>();
IResponse<string> response = new ApiResponse<string>(); IResponse<string> response = new ApiResponse<string>();
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -39,7 +39,7 @@ namespace Octokit.Tests.Http
req.ContentType == null && req.ContentType == null &&
req.Body == null && req.Body == null &&
req.Method == HttpMethod.Get && req.Method == HttpMethod.Get &&
req.Endpoint == new Uri("endpoint", UriKind.Relative))); req.Endpoint == new Uri("endpoint", UriKind.Relative)), Args.CancellationToken);
} }
[Fact] [Fact]
@@ -47,7 +47,7 @@ namespace Octokit.Tests.Http
{ {
var httpClient = Substitute.For<IHttpClient>(); var httpClient = Substitute.For<IHttpClient>();
IResponse<string> response = new ApiResponse<string>(); IResponse<string> response = new ApiResponse<string>();
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -61,7 +61,7 @@ namespace Octokit.Tests.Http
httpClient.Received(3).Send<string>(Arg.Is<IRequest>(req => httpClient.Received(3).Send<string>(Arg.Is<IRequest>(req =>
req.BaseAddress == ExampleUri && req.BaseAddress == ExampleUri &&
req.Method == HttpMethod.Get && req.Method == HttpMethod.Get &&
req.Endpoint == new Uri("endpoint", UriKind.Relative))); req.Endpoint == new Uri("endpoint", UriKind.Relative)), Args.CancellationToken);
} }
[Fact] [Fact]
@@ -76,7 +76,7 @@ namespace Octokit.Tests.Http
} }
}; };
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -93,7 +93,7 @@ namespace Octokit.Tests.Http
{ {
var httpClient = Substitute.For<IHttpClient>(); var httpClient = Substitute.For<IHttpClient>();
IResponse<string> response = new ApiResponse<string> { StatusCode = HttpStatusCode.Unauthorized}; IResponse<string> response = new ApiResponse<string> { StatusCode = HttpStatusCode.Unauthorized};
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -117,7 +117,7 @@ namespace Octokit.Tests.Http
var httpClient = Substitute.For<IHttpClient>(); var httpClient = Substitute.For<IHttpClient>();
IResponse<string> response = new ApiResponse<string> { StatusCode = HttpStatusCode.Unauthorized }; IResponse<string> response = new ApiResponse<string> { StatusCode = HttpStatusCode.Unauthorized };
response.Headers[headerKey] = otpHeaderValue; response.Headers[headerKey] = otpHeaderValue;
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -147,7 +147,7 @@ namespace Octokit.Tests.Http
StatusCode = HttpStatusCode.Unauthorized, StatusCode = HttpStatusCode.Unauthorized,
}; };
response.Headers[headerKey] = otpHeaderValue; response.Headers[headerKey] = otpHeaderValue;
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -170,7 +170,7 @@ namespace Octokit.Tests.Http
Body = @"{""errors"":[{""code"":""custom"",""field"":""key"",""message"":""key is " + Body = @"{""errors"":[{""code"":""custom"",""field"":""key"",""message"":""key is " +
@"already in use"",""resource"":""PublicKey""}],""message"":""Validation Failed""}" @"already in use"",""resource"":""PublicKey""}],""message"":""Validation Failed""}"
}; };
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -194,7 +194,7 @@ namespace Octokit.Tests.Http
Body = "{\"message\":\"API rate limit exceeded. " + Body = "{\"message\":\"API rate limit exceeded. " +
"See http://developer.github.com/v3/#rate-limiting for details.\"}" "See http://developer.github.com/v3/#rate-limiting for details.\"}"
}; };
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -218,7 +218,7 @@ namespace Octokit.Tests.Http
Body = "{\"message\":\"Maximum number of login attempts exceeded\"," + Body = "{\"message\":\"Maximum number of login attempts exceeded\"," +
"\"documentation_url\":\"http://developer.github.com/v3\"}" "\"documentation_url\":\"http://developer.github.com/v3\"}"
}; };
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -241,7 +241,7 @@ namespace Octokit.Tests.Http
StatusCode = HttpStatusCode.NotFound, StatusCode = HttpStatusCode.NotFound,
Body = "GONE BYE BYE!" Body = "GONE BYE BYE!"
}; };
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -263,7 +263,7 @@ namespace Octokit.Tests.Http
StatusCode = HttpStatusCode.Forbidden, StatusCode = HttpStatusCode.Forbidden,
Body = "YOU SHALL NOT PASS!" Body = "YOU SHALL NOT PASS!"
}; };
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -284,7 +284,7 @@ namespace Octokit.Tests.Http
{ {
var httpClient = Substitute.For<IHttpClient>(); var httpClient = Substitute.For<IHttpClient>();
IResponse<string> response = new ApiResponse<string>(); IResponse<string> response = new ApiResponse<string>();
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -299,7 +299,7 @@ namespace Octokit.Tests.Http
req.Body == null && req.Body == null &&
req.Method == HttpMethod.Get && req.Method == HttpMethod.Get &&
req.Headers["Accept"] == "application/vnd.github.html" && req.Headers["Accept"] == "application/vnd.github.html" &&
req.Endpoint == new Uri("endpoint", UriKind.Relative))); req.Endpoint == new Uri("endpoint", UriKind.Relative)), Args.CancellationToken);
} }
} }
@@ -311,7 +311,7 @@ namespace Octokit.Tests.Http
string data = SimpleJson.SerializeObject(new object()); string data = SimpleJson.SerializeObject(new object());
var httpClient = Substitute.For<IHttpClient>(); var httpClient = Substitute.For<IHttpClient>();
IResponse<string> response = new ApiResponse<string>(); IResponse<string> response = new ApiResponse<string>();
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -325,7 +325,7 @@ namespace Octokit.Tests.Http
(string)req.Body == data && (string)req.Body == data &&
req.Method == HttpVerb.Patch && req.Method == HttpVerb.Patch &&
req.ContentType == "application/x-www-form-urlencoded" && req.ContentType == "application/x-www-form-urlencoded" &&
req.Endpoint == new Uri("endpoint", UriKind.Relative))); req.Endpoint == new Uri("endpoint", UriKind.Relative)), Args.CancellationToken);
} }
} }
@@ -337,7 +337,7 @@ namespace Octokit.Tests.Http
string data = SimpleJson.SerializeObject(new object()); string data = SimpleJson.SerializeObject(new object());
var httpClient = Substitute.For<IHttpClient>(); var httpClient = Substitute.For<IHttpClient>();
IResponse<string> response = new ApiResponse<string>(); IResponse<string> response = new ApiResponse<string>();
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -351,7 +351,7 @@ namespace Octokit.Tests.Http
(string)req.Body == data && (string)req.Body == data &&
req.Method == HttpMethod.Put && req.Method == HttpMethod.Put &&
req.ContentType == "application/x-www-form-urlencoded" && req.ContentType == "application/x-www-form-urlencoded" &&
req.Endpoint == new Uri("endpoint", UriKind.Relative))); req.Endpoint == new Uri("endpoint", UriKind.Relative)), Args.CancellationToken);
} }
[Fact] [Fact]
@@ -360,7 +360,7 @@ namespace Octokit.Tests.Http
string data = SimpleJson.SerializeObject(new object()); string data = SimpleJson.SerializeObject(new object());
var httpClient = Substitute.For<IHttpClient>(); var httpClient = Substitute.For<IHttpClient>();
IResponse<string> response = new ApiResponse<string>(); IResponse<string> response = new ApiResponse<string>();
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -375,7 +375,7 @@ namespace Octokit.Tests.Http
req.Method == HttpMethod.Put && req.Method == HttpMethod.Put &&
req.Headers["X-GitHub-OTP"] == "two-factor" && req.Headers["X-GitHub-OTP"] == "two-factor" &&
req.ContentType == "application/x-www-form-urlencoded" && req.ContentType == "application/x-www-form-urlencoded" &&
req.Endpoint == new Uri("endpoint", UriKind.Relative))); req.Endpoint == new Uri("endpoint", UriKind.Relative)), Args.CancellationToken);
} }
} }
@@ -387,7 +387,7 @@ namespace Octokit.Tests.Http
string data = SimpleJson.SerializeObject(new object()); string data = SimpleJson.SerializeObject(new object());
var httpClient = Substitute.For<IHttpClient>(); var httpClient = Substitute.For<IHttpClient>();
IResponse<string> response = new ApiResponse<string>(); IResponse<string> response = new ApiResponse<string>();
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -401,7 +401,7 @@ namespace Octokit.Tests.Http
req.ContentType == "application/x-www-form-urlencoded" && req.ContentType == "application/x-www-form-urlencoded" &&
(string)req.Body == data && (string)req.Body == data &&
req.Method == HttpMethod.Post && req.Method == HttpMethod.Post &&
req.Endpoint == new Uri("endpoint", UriKind.Relative))); req.Endpoint == new Uri("endpoint", UriKind.Relative)), Args.CancellationToken);
} }
[Fact] [Fact]
@@ -409,7 +409,7 @@ namespace Octokit.Tests.Http
{ {
var httpClient = Substitute.For<IHttpClient>(); var httpClient = Substitute.For<IHttpClient>();
IResponse<string> response = new ApiResponse<string>(); IResponse<string> response = new ApiResponse<string>();
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -429,7 +429,7 @@ namespace Octokit.Tests.Http
req.Headers["Accept"] == "application/vnd.github.v3+json; charset=utf-8" && req.Headers["Accept"] == "application/vnd.github.v3+json; charset=utf-8" &&
req.ContentType == "application/arbitrary" && req.ContentType == "application/arbitrary" &&
req.Method == HttpMethod.Post && req.Method == HttpMethod.Post &&
req.Endpoint == new Uri("https://other.host.com/path?query=val"))); req.Endpoint == new Uri("https://other.host.com/path?query=val")), Args.CancellationToken);
} }
[Fact] [Fact]
@@ -437,7 +437,7 @@ namespace Octokit.Tests.Http
{ {
var httpClient = Substitute.For<IHttpClient>(); var httpClient = Substitute.For<IHttpClient>();
IResponse<string> response = new ApiResponse<string>(); IResponse<string> response = new ApiResponse<string>();
httpClient.Send<string>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<string>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -453,7 +453,7 @@ namespace Octokit.Tests.Http
httpClient.Received().Send<string>(Arg.Is<IRequest>(req => httpClient.Received().Send<string>(Arg.Is<IRequest>(req =>
req.Headers["Accept"] == "application/json" && req.Headers["Accept"] == "application/json" &&
req.ContentType == "application/x-www-form-urlencoded")); req.ContentType == "application/x-www-form-urlencoded"), Args.CancellationToken);
} }
} }
@@ -464,7 +464,7 @@ namespace Octokit.Tests.Http
{ {
var httpClient = Substitute.For<IHttpClient>(); var httpClient = Substitute.For<IHttpClient>();
IResponse<object> response = new ApiResponse<object>(); IResponse<object> response = new ApiResponse<object>();
httpClient.Send<object>(Args.Request).Returns(Task.FromResult(response)); httpClient.Send<object>(Args.Request, Args.CancellationToken).Returns(Task.FromResult(response));
var connection = new Connection(new ProductHeaderValue("OctokitTests"), var connection = new Connection(new ProductHeaderValue("OctokitTests"),
ExampleUri, ExampleUri,
Substitute.For<ICredentialStore>(), Substitute.For<ICredentialStore>(),
@@ -478,7 +478,7 @@ namespace Octokit.Tests.Http
req.Body == null && req.Body == null &&
req.ContentType == null && req.ContentType == null &&
req.Method == HttpMethod.Delete && req.Method == HttpMethod.Delete &&
req.Endpoint == new Uri("endpoint", UriKind.Relative))); req.Endpoint == new Uri("endpoint", UriKind.Relative)), Args.CancellationToken);
} }
} }

View File

@@ -0,0 +1,86 @@
using Octokit.Internal;
using System;
using System.Collections.Generic;
using Xunit;
namespace Octokit.Tests.Models
{
public class DeploymentStatusTests
{
[Fact]
public void CanDeserialize()
{
var expected = new DeploymentStatus
{
Id = 1,
Url = "https://api.github.com/repos/octocat/example/deployments/1/statuses/42",
State = DeploymentState.Success,
Payload = "{\"environment\":\"production\"}",
TargetUrl = "https://gist.github.com/628b2736d379f",
CreatedAt = DateTimeOffset.Parse("2012-07-20T01:19:13Z"),
UpdatedAt = DateTimeOffset.Parse("2012-07-20T01:19:13Z"),
Description = "Deploy request from hubot"
};
var json =
@"{
""id"": 1,
""url"": ""https://api.github.com/repos/octocat/example/deployments/1/statuses/42"",
""state"": ""success"",
""creator"": {
""login"": ""octocat"",
""id"": 1,
""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"",
""gravatar_id"": ""somehexcode"",
""url"": ""https://api.github.com/users/octocat"",
""html_url"": ""https://github.com/octocat"",
""followers_url"": ""https://api.github.com/users/octocat/followers"",
""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"",
""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"",
""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"",
""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"",
""organizations_url"": ""https://api.github.com/users/octocat/orgs"",
""repos_url"": ""https://api.github.com/users/octocat/repos"",
""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"",
""received_events_url"": ""https://api.github.com/users/octocat/received_events"",
""type"": ""User"",
""site_admin"": false
},
""payload"": ""{\""environment\"":\""production\""}"",
""target_url"": ""https://gist.github.com/628b2736d379f"",
""created_at"": ""2012-07-20T01:19:13Z"",
""updated_at"": ""2012-07-20T01:19:13Z"",
""description"": ""Deploy request from hubot""
}";
var actual = new SimpleJsonSerializer().Deserialize<DeploymentStatus>(json);
Assert.Equal(expected, actual, new DeploymentStatusEqualityComparer());
}
}
public class DeploymentStatusEqualityComparer : IEqualityComparer<DeploymentStatus>
{
public bool Equals(DeploymentStatus x, DeploymentStatus y)
{
if (x == null && y == null)
return true;
if (x == null || y == null)
return false;
return x.Id == y.Id &&
x.Url == y.Url &&
x.State == y.State &&
x.Payload == y.Payload &&
x.TargetUrl == y.TargetUrl &&
x.CreatedAt == y.CreatedAt &&
x.UpdatedAt == y.UpdatedAt &&
x.Description == y.Description;
}
public int GetHashCode(DeploymentStatus obj)
{
throw new System.NotImplementedException();
}
}
}

View File

@@ -0,0 +1,89 @@
using Octokit.Internal;
using System;
using System.Collections.Generic;
using Xunit;
namespace Octokit.Tests.Models
{
public class DeploymentTests
{
[Fact]
public void CanDeserialize()
{
var expected = new Deployment {
Id = 1,
Sha = "topic-branch",
Url = "https://api.github.com/repos/octocat/example/deployments/1",
Payload = "{\"environment\":\"production\"}",
CreatedAt = DateTimeOffset.Parse("2012-07-20T01:19:13Z"),
UpdatedAt = DateTimeOffset.Parse("2012-07-20T01:19:13Z"),
Description = "Deploy request from hubot",
StatusesUrl = "https://api.github.com/repos/octocat/example/deployments/1/statuses"
};
var json =
@"{
""id"": 1,
""sha"": ""topic-branch"",
""url"": ""https://api.github.com/repos/octocat/example/deployments/1"",
""creator"": {
""login"": ""octocat"",
""id"": 1,
""avatar_url"": ""https://github.com/images/error/octocat_happy.gif"",
""gravatar_id"": ""somehexcode"",
""url"": ""https://api.github.com/users/octocat"",
""html_url"": ""https://github.com/octocat"",
""followers_url"": ""https://api.github.com/users/octocat/followers"",
""following_url"": ""https://api.github.com/users/octocat/following{/other_user}"",
""gists_url"": ""https://api.github.com/users/octocat/gists{/gist_id}"",
""starred_url"": ""https://api.github.com/users/octocat/starred{/owner}{/repo}"",
""subscriptions_url"": ""https://api.github.com/users/octocat/subscriptions"",
""organizations_url"": ""https://api.github.com/users/octocat/orgs"",
""repos_url"": ""https://api.github.com/users/octocat/repos"",
""events_url"": ""https://api.github.com/users/octocat/events{/privacy}"",
""received_events_url"": ""https://api.github.com/users/octocat/received_events"",
""type"": ""User"",
""site_admin"": false
},
""payload"": ""{\""environment\"":\""production\""}"",
""created_at"": ""2012-07-20T01:19:13Z"",
""updated_at"": ""2012-07-20T01:19:13Z"",
""description"": ""Deploy request from hubot"",
""statuses_url"": ""https://api.github.com/repos/octocat/example/deployments/1/statuses""
}";
var actual = new SimpleJsonSerializer().Deserialize<Deployment>(json);
Assert.Equal(expected, actual, new DeploymentEqualityComparer());
}
}
// Equaliy for the sake of testing serialization/deserialization.
// Actual production equality should most likely just be a check
// of `Url` equality.
public class DeploymentEqualityComparer : IEqualityComparer<Deployment>
{
public bool Equals(Deployment x, Deployment y)
{
if (x == null && y == null)
return true;
if (x == null || y == null)
return false;
return x.Id == y.Id &&
x.Sha == y .Sha &&
x.Url == y.Url &&
x.Payload == y.Payload &&
x.CreatedAt == y.CreatedAt &&
x.UpdatedAt == y.UpdatedAt &&
x.Description == y.Description &&
x.StatusesUrl == y.StatusesUrl;
}
public int GetHashCode(Deployment obj)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using Octokit.Response;
using Xunit;
namespace Octokit.Tests.Models
{
public class PunchCardTests
{
[Fact]
public void ThrowsExceptionWithNullPunchCardPoints()
{
Assert.Throws<ArgumentNullException>(()=>new PunchCard(null));
}
[Fact]
public void ThrowsExceptionWhenPunchCardPointsHaveIncorrectFormat()
{
IList<int> point1 = new []{1,2,3,4,5,6};
IEnumerable<IList<int>> points = new List<IList<int>>{point1};
Assert.Throws<ArgumentException>(() => new PunchCard(points));
}
[Fact]
public void DoesNotThrowExceptionWhenPunchPointsHaveCorrectFormat()
{
IList<int> point1 = new[] { 1, 2, 3};
IEnumerable<IList<int>> points = new List<IList<int>> { point1 };
Assert.DoesNotThrow(() => new PunchCard(points));
}
[Fact]
public void CanQueryCommitsForDayAndHour()
{
IList<int> point1 = new[] { 1, 0, 3 };
IList<int> point2 = new[] { 1, 1, 4 };
IList<int> point3 = new[] { 1, 2, 0 };
IEnumerable<IList<int>> points = new List<IList<int>> { point1,point2,point3 };
var punchCard = new PunchCard(points);
var commitsAtMondayAt12Am = punchCard.GetCommitCountFor(DayOfWeek.Monday, 0);
var commitsAtMondayAt1Am = punchCard.GetCommitCountFor(DayOfWeek.Monday, 1);
var commitsAtMondayAt2Am = punchCard.GetCommitCountFor(DayOfWeek.Monday, 2);
var commitsAtTuesdayAt2Am = punchCard.GetCommitCountFor(DayOfWeek.Tuesday, 2);
Assert.Equal(3,commitsAtMondayAt12Am);
Assert.Equal(4, commitsAtMondayAt1Am);
Assert.Equal(0, commitsAtMondayAt2Am);
Assert.Equal(0, commitsAtTuesdayAt2Am);
}
}
}

View File

@@ -0,0 +1,40 @@
using Octokit.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace Octokit.Tests.Models
{
public class RepositoryUpdateTests
{
[Fact]
public void CanSerialize()
{
var expected = "{\"name\":\"Hello-World\"," +
"\"description\":\"This is your first repository\"," +
"\"homepage\":\"https://github.com\"," +
"\"private\":true," +
"\"has_issues\":true," +
"\"has_wiki\":true," +
"\"has_downloads\":true}";
var update = new RepositoryUpdate
{
Name = "Hello-World",
Description = "This is your first repository",
Homepage = "https://github.com",
Private = true,
HasIssues = true,
HasWiki = true,
HasDownloads = true
};
var json = new SimpleJsonSerializer().Serialize(update);
Assert.Equal(expected, json);
}
}
}

View File

@@ -41,13 +41,13 @@
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
<Reference Include="System.Reactive.Core"> <Reference Include="System.Reactive.Core">
<HintPath>..\packages\Rx-Core.2.1.30214.0\lib\Net45\System.Reactive.Core.dll</HintPath> <HintPath>..\packages\Rx-Core.2.2.2\lib\net45\System.Reactive.Core.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Reactive.Interfaces"> <Reference Include="System.Reactive.Interfaces">
<HintPath>..\packages\Rx-Interfaces.2.1.30214.0\lib\Net45\System.Reactive.Interfaces.dll</HintPath> <HintPath>..\packages\Rx-Interfaces.2.2.2\lib\net45\System.Reactive.Interfaces.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Reactive.Linq"> <Reference Include="System.Reactive.Linq">
<HintPath>..\packages\Rx-Linq.2.1.30214.0\lib\Net45\System.Reactive.Linq.dll</HintPath> <HintPath>..\packages\Rx-Linq.2.2.2\lib\net45\System.Reactive.Linq.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.XML" /> <Reference Include="System.XML" />
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
@@ -62,6 +62,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Authentication\CredentialsTests.cs" /> <Compile Include="Authentication\CredentialsTests.cs" />
<Compile Include="Clients\DeploymentsClientTests.cs" />
<Compile Include="Clients\DeploymentStatusClientTests.cs" />
<Compile Include="Clients\SearchClientTests.cs" /> <Compile Include="Clients\SearchClientTests.cs" />
<Compile Include="Clients\GistCommentsClientTests.cs" /> <Compile Include="Clients\GistCommentsClientTests.cs" />
<Compile Include="Clients\GistsClientTests.cs" /> <Compile Include="Clients\GistsClientTests.cs" />
@@ -73,6 +75,7 @@
<Compile Include="Clients\AssigneesClientTests.cs" /> <Compile Include="Clients\AssigneesClientTests.cs" />
<Compile Include="Clients\CommitsClientTests.cs" /> <Compile Include="Clients\CommitsClientTests.cs" />
<Compile Include="Clients\CommitStatusClientTests.cs" /> <Compile Include="Clients\CommitStatusClientTests.cs" />
<Compile Include="Clients\StatisticsClientTests.cs" />
<Compile Include="Clients\TeamsClientTests.cs" /> <Compile Include="Clients\TeamsClientTests.cs" />
<Compile Include="Clients\GitDatabaseClientTests.cs" /> <Compile Include="Clients\GitDatabaseClientTests.cs" />
<Compile Include="Clients\OrganizationMembersClientTests.cs" /> <Compile Include="Clients\OrganizationMembersClientTests.cs" />
@@ -87,6 +90,7 @@
<Compile Include="Clients\ReleasesClientTests.cs" /> <Compile Include="Clients\ReleasesClientTests.cs" />
<Compile Include="Clients\SshKeysClientTests.cs" /> <Compile Include="Clients\SshKeysClientTests.cs" />
<Compile Include="Clients\TreesClientTests.cs" /> <Compile Include="Clients\TreesClientTests.cs" />
<Compile Include="Clients\UserEmailsClientTests.cs" />
<Compile Include="Clients\WatchedClientTests.cs" /> <Compile Include="Clients\WatchedClientTests.cs" />
<Compile Include="Clients\FollowersClientTests.cs" /> <Compile Include="Clients\FollowersClientTests.cs" />
<Compile Include="Exceptions\ApiExceptionTests.cs" /> <Compile Include="Exceptions\ApiExceptionTests.cs" />
@@ -118,12 +122,16 @@
<Compile Include="Http\ResponseTests.cs" /> <Compile Include="Http\ResponseTests.cs" />
<Compile Include="Http\RequestTests.cs" /> <Compile Include="Http\RequestTests.cs" />
<Compile Include="Models\CommitTests.cs" /> <Compile Include="Models\CommitTests.cs" />
<Compile Include="Models\DeploymentStatusTests.cs" />
<Compile Include="Models\DeploymentTests.cs" />
<Compile Include="Models\NewReferenceTests.cs" /> <Compile Include="Models\NewReferenceTests.cs" />
<Compile Include="Models\MilestoneRequestTests.cs" /> <Compile Include="Models\MilestoneRequestTests.cs" />
<Compile Include="Models\IssueRequestTests.cs" /> <Compile Include="Models\IssueRequestTests.cs" />
<Compile Include="Models\ModelExtensionsTests.cs" /> <Compile Include="Models\ModelExtensionsTests.cs" />
<Compile Include="Models\PullRequestRequestTests.cs" /> <Compile Include="Models\PullRequestRequestTests.cs" />
<Compile Include="Models\PunchCardTests.cs" />
<Compile Include="Models\ReadOnlyPagedCollectionTests.cs" /> <Compile Include="Models\ReadOnlyPagedCollectionTests.cs" />
<Compile Include="Models\RepositoryUpdateTests.cs" />
<Compile Include="Models\RequestParametersTests.cs" /> <Compile Include="Models\RequestParametersTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Helpers\StringExtensionsTests.cs" /> <Compile Include="Helpers\StringExtensionsTests.cs" />
@@ -131,16 +139,21 @@
<Compile Include="Reactive\AuthorizationExtensionsTests.cs" /> <Compile Include="Reactive\AuthorizationExtensionsTests.cs" />
<Compile Include="Reactive\ObservableBlobClientTests.cs" /> <Compile Include="Reactive\ObservableBlobClientTests.cs" />
<Compile Include="Reactive\ObservableCommitsClientTests.cs" /> <Compile Include="Reactive\ObservableCommitsClientTests.cs" />
<Compile Include="Reactive\ObservableDeploymentsClientTests.cs" />
<Compile Include="Reactive\ObservableDeploymentStatusClientTests.cs" />
<Compile Include="Reactive\ObservableEventsClientTests.cs" /> <Compile Include="Reactive\ObservableEventsClientTests.cs" />
<Compile Include="Reactive\ObservableIssueCommentsClientTests.cs" /> <Compile Include="Reactive\ObservableIssueCommentsClientTests.cs" />
<Compile Include="Reactive\ObservableIssuesClientTests.cs" /> <Compile Include="Reactive\ObservableIssuesClientTests.cs" />
<Compile Include="Reactive\ObservableMilestonesClientTests.cs" /> <Compile Include="Reactive\ObservableMilestonesClientTests.cs" />
<Compile Include="Reactive\ObservableOrganizationMembersClientTests.cs" /> <Compile Include="Reactive\ObservableOrganizationMembersClientTests.cs" />
<Compile Include="Reactive\ObservablePullRequestsClientTests.cs" /> <Compile Include="Reactive\ObservablePullRequestsClientTests.cs" />
<Compile Include="Reactive\ObservableReleasesClientTests.cs" />
<Compile Include="Reactive\ObservableRepositoriesClientTests.cs" /> <Compile Include="Reactive\ObservableRepositoriesClientTests.cs" />
<Compile Include="Reactive\ObservableStarredClientTests.cs" /> <Compile Include="Reactive\ObservableStarredClientTests.cs" />
<Compile Include="Reactive\ObservableStatisticsClientTests.cs" />
<Compile Include="Reactive\ObservableTreesClientTests.cs" /> <Compile Include="Reactive\ObservableTreesClientTests.cs" />
<Compile Include="Reactive\ObservableFollowersTest.cs" /> <Compile Include="Reactive\ObservableFollowersTest.cs" />
<Compile Include="Reactive\ObservableUserEmailsClientTests.cs" />
<Compile Include="SimpleJsonSerializerTests.cs" /> <Compile Include="SimpleJsonSerializerTests.cs" />
<Compile Include="Clients\UsersClientTests.cs" /> <Compile Include="Clients\UsersClientTests.cs" />
</ItemGroup> </ItemGroup>

View File

@@ -43,8 +43,7 @@ namespace Octokit.Tests.Reactive
client.Get("owner", "name", "reference"); client.Get("owner", "name", "reference");
gitHubClient.Connection.GetAsync<IReadOnlyList<GitHubClient>>( gitHubClient.GitDatabase.Commit.Received(1).Get("owner", "name", "reference");
new Uri("repos/owner/name/commits/reference", UriKind.Relative), null, null);
} }
} }

View File

@@ -0,0 +1,146 @@
using NSubstitute;
using Octokit.Reactive.Clients;
using Octokit.Tests.Helpers;
using System;
using System.Collections.Generic;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Xunit;
namespace Octokit.Tests.Reactive
{
public class ObservableDeploymentStatusClientTests
{
const string ExpectedAcceptHeader = "application/vnd.github.cannonball-preview+json";
public class TheGetAllMethod
{
readonly IGitHubClient _githubClient;
readonly ObservableDeploymentStatusClient _client;
public TheGetAllMethod()
{
_githubClient = new GitHubClient(Substitute.For<IConnection>());
_client = new ObservableDeploymentStatusClient(_githubClient);
}
[Fact]
public void EnsuresNonNullArguments()
{
Assert.Throws<ArgumentNullException>(() => _client.GetAll(null, "repo", 1));
Assert.Throws<ArgumentNullException>(() => _client.GetAll("owner", null, 1));
}
[Fact]
public void EnsuresNonEmptyArguments()
{
Assert.Throws<ArgumentException>(() => _client.GetAll("", "repo", 1));
Assert.Throws<ArgumentException>(() => _client.GetAll("owner", "", 1));
}
[Fact]
public async Task EnsureNonWhitespaceArguments()
{
await AssertEx.ThrowsWhenGivenWhitespaceArgument(
async whitespace => await _client.GetAll(whitespace, "repo", 1));
await AssertEx.ThrowsWhenGivenWhitespaceArgument(
async whitespace => await _client.GetAll("owner", whitespace, 1));
}
[Fact]
public void GetsFromCorrectUrl()
{
var expectedUri = ApiUrls.DeploymentStatuses("owner", "repo", 1);
_client.GetAll("owner", "repo", 1);
_githubClient.Connection.Received(1)
.GetAsync<List<DeploymentStatus>>(Arg.Is(expectedUri),
Arg.Any<IDictionary<string, string>>(),
Arg.Any<string>());
}
[Fact]
public void UsesPreviewAcceptHeader()
{
_client.GetAll("owner", "repo", 1);
_githubClient.Connection
.Received(1)
.GetAsync<List<DeploymentStatus>>(Arg.Any<Uri>(),
Arg.Any<IDictionary<string, string>>(),
Arg.Is(ExpectedAcceptHeader));
}
}
public class TheCreateMethod
{
IGitHubClient _githubClient = Substitute.For<IGitHubClient>();
ObservableDeploymentStatusClient _client;
public void SetupWithoutNonReactiveClient()
{
_client = new ObservableDeploymentStatusClient(_githubClient);
}
public void SetupWithNonReactiveClient()
{
var deploymentStatusClient = new DeploymentStatusClient(Substitute.For<IApiConnection>());
_githubClient.Deployment.Status.Returns(deploymentStatusClient);
_client = new ObservableDeploymentStatusClient(_githubClient);
}
[Fact]
public async Task EnsuresNonNullArguments()
{
SetupWithNonReactiveClient();
Assert.Throws<ArgumentNullException>(() => _client.Create(null, "repo", 1, new NewDeploymentStatus()));
Assert.Throws<ArgumentNullException>(() => _client.Create("owner", null, 1, new NewDeploymentStatus()));
Assert.Throws<ArgumentNullException>(() => _client.Create("owner", "repo", 1, null));
}
[Fact]
public async Task EnsuresNonEmptyArguments()
{
SetupWithNonReactiveClient();
Assert.Throws<ArgumentException>(() => _client.Create("", "repo", 1, new NewDeploymentStatus()));
Assert.Throws<ArgumentException>(() => _client.Create("owner", "", 1, new NewDeploymentStatus()));
}
[Fact]
public async Task EnsureNonWhitespaceArguments()
{
SetupWithNonReactiveClient();
await AssertEx.ThrowsWhenGivenWhitespaceArgument(
async whitespace => await _client.Create(whitespace, "repo", 1, new NewDeploymentStatus()));
await AssertEx.ThrowsWhenGivenWhitespaceArgument(
async whitespace => await _client.Create("owner", whitespace, 1, new NewDeploymentStatus()));
}
[Fact]
public void CallsIntoDeploymentStatusClient()
{
SetupWithoutNonReactiveClient();
var newStatus = new NewDeploymentStatus();
_client.Create("owner", "repo", 1, newStatus);
_githubClient.Deployment.Status.Received(1)
.Create(Arg.Is("owner"),
Arg.Is("repo"),
Arg.Is(1),
Arg.Is(newStatus));
}
}
public class TheCtor
{
[Fact]
public void EnsuresArgument()
{
Assert.Throws<ArgumentNullException>(
() => new ObservableDeploymentStatusClient(null));
}
}
}
}

View File

@@ -0,0 +1,149 @@
using NSubstitute;
using Octokit.Reactive.Clients;
using Octokit.Tests.Helpers;
using System;
using System.Collections.Generic;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Xunit;
using System.Linq;
namespace Octokit.Tests.Reactive
{
public class ObservableDeploymentsClientTests
{
const string ExpectedAcceptHeader = "application/vnd.github.cannonball-preview+json";
public class TheGetAllMethod
{
readonly IGitHubClient _githubClient;
readonly ObservableDeploymentsClient _client;
public TheGetAllMethod()
{
_githubClient = Substitute.For<IGitHubClient>();
_client = new ObservableDeploymentsClient(_githubClient);
}
[Fact]
public void EnsuresNonNullArguments()
{
Assert.Throws<ArgumentNullException>(() => _client.GetAll(null, "repo"));
Assert.Throws<ArgumentNullException>(() => _client.GetAll("owner", null));
}
[Fact]
public void EnsuresNonEmptyArguments()
{
Assert.Throws<ArgumentException>(() => _client.GetAll("", "repo"));
Assert.Throws<ArgumentException>(() => _client.GetAll("owner", ""));
}
[Fact]
public async Task EnsuresNonWhitespaceArguments()
{
await AssertEx.ThrowsWhenGivenWhitespaceArgument(
async whitespace => await _client.GetAll(whitespace, "repo"));
await AssertEx.ThrowsWhenGivenWhitespaceArgument(
async whitespace => await _client.GetAll("owner", whitespace));
}
[Fact]
public void CallsDeploymentsUrl()
{
var expectedUri = ApiUrls.Deployments("owner", "repo");
_client.GetAll("owner", "repo");
_githubClient.Connection
.Received(1)
.GetAsync<List<Deployment>>(Arg.Is(expectedUri),
Arg.Any<IDictionary<string, string>>(),
Arg.Any<string>());
}
[Fact]
public void UsesPreviewAcceptHeader()
{
_client.GetAll("owner", "repo");
_githubClient.Connection.Received(1)
.GetAsync<List<Deployment>>(Arg.Any<Uri>(),
Arg.Any<IDictionary<string, string>>(),
ExpectedAcceptHeader);
}
}
public class TheCreateMethod
{
IGitHubClient _githubClient;
ObservableDeploymentsClient _client;
public TheCreateMethod()
{
_githubClient = Substitute.For<IGitHubClient>();
}
private void SetupWithoutNonReactiveClient()
{
_client = new ObservableDeploymentsClient(_githubClient);
}
private void SetupWithNonReactiveClient()
{
var deploymentsClient = new DeploymentsClient(Substitute.For<IApiConnection>());
_githubClient.Deployment.Returns(deploymentsClient);
_client = new ObservableDeploymentsClient(_githubClient);
}
[Fact]
public void EnsuresNonNullArguments()
{
SetupWithNonReactiveClient();
Assert.Throws<ArgumentNullException>(() => _client.Create(null, "repo", new NewDeployment()));
Assert.Throws<ArgumentNullException>(() => _client.Create("owner", null, new NewDeployment()));
Assert.Throws<ArgumentNullException>(() => _client.Create("owner", "repo", null));
}
[Fact]
public void EnsuresNonEmptyArguments()
{
SetupWithNonReactiveClient();
Assert.Throws<ArgumentException>(() => _client.Create("", "repo", new NewDeployment()));
Assert.Throws<ArgumentException>(() => _client.Create("owner", "", new NewDeployment()));
}
[Fact]
public async Task EnsuresNonWhitespaceArguments()
{
SetupWithNonReactiveClient();
await AssertEx.ThrowsWhenGivenWhitespaceArgument(
async whitespace => await _client.Create(whitespace, "repo", new NewDeployment()));
await AssertEx.ThrowsWhenGivenWhitespaceArgument(
async whitespace => await _client.Create("owner", whitespace, new NewDeployment()));
}
[Fact]
public void CallsCreateOnRegularDeploymentsClient()
{
SetupWithoutNonReactiveClient();
var newDeployment = new NewDeployment();
_client.Create("owner", "repo", newDeployment);
_githubClient.Deployment.Received(1).Create(Arg.Is("owner"),
Arg.Is("repo"),
Arg.Is(newDeployment));
}
}
public class TheCtor
{
[Fact]
public void EnsuresArguments()
{
Assert.Throws<ArgumentNullException>(() => new ObservableDeploymentsClient(null));
}
}
}
}

View File

@@ -21,7 +21,7 @@ namespace Octokit.Tests.Reactive
client.GetAll(); client.GetAll();
gitHubClient.Connection.GetAsync<IReadOnlyList<Activity>>(new Uri("events", UriKind.Relative), null, null); gitHubClient.Connection.Received(1).GetAsync<List<Activity>>(new Uri("events", UriKind.Relative), null, null);
} }
} }
@@ -35,7 +35,7 @@ namespace Octokit.Tests.Reactive
client.GetAllForRepository("fake", "repo"); client.GetAllForRepository("fake", "repo");
gitHubClient.Connection.GetAsync<IReadOnlyList<Activity>>(new Uri("repos/fake/repo/issues/events", UriKind.Relative), null, null); gitHubClient.Connection.Received(1).GetAsync<List<Activity>>(new Uri("repos/fake/repo/issues/events", UriKind.Relative), null, null);
} }
[Fact] [Fact]
@@ -61,7 +61,7 @@ namespace Octokit.Tests.Reactive
client.GetAllForRepositoryNetwork("fake", "repo"); client.GetAllForRepositoryNetwork("fake", "repo");
gitHubClient.Connection.GetAsync<IReadOnlyList<Activity>>(new Uri("networks/fake/repo/events", UriKind.Relative), null, null); gitHubClient.Connection.Received(1).GetAsync<List<Activity>>(new Uri("networks/fake/repo/events", UriKind.Relative), null, null);
} }
[Fact] [Fact]
@@ -87,7 +87,7 @@ namespace Octokit.Tests.Reactive
client.GetAllForOrganization("fake"); client.GetAllForOrganization("fake");
gitHubClient.Connection.GetAsync<IReadOnlyList<Activity>>(new Uri("orgs/fake/events", UriKind.Relative), null, null); gitHubClient.Connection.Received(1).GetAsync<List<Activity>>(new Uri("orgs/fake/events", UriKind.Relative), null, null);
} }
[Fact] [Fact]
@@ -111,7 +111,7 @@ namespace Octokit.Tests.Reactive
client.GetUserReceived("fake"); client.GetUserReceived("fake");
gitHubClient.Connection.GetAsync<IReadOnlyList<Activity>>(new Uri("users/fake/received_events", UriKind.Relative), null, null); gitHubClient.Connection.Received(1).GetAsync<List<Activity>>(new Uri("users/fake/received_events", UriKind.Relative), null, null);
} }
[Fact] [Fact]
@@ -135,7 +135,7 @@ namespace Octokit.Tests.Reactive
client.GetUserReceivedPublic("fake"); client.GetUserReceivedPublic("fake");
gitHubClient.Connection.GetAsync<IReadOnlyList<Activity>>(new Uri("users/fake/received_events/public", UriKind.Relative), null, null); gitHubClient.Connection.Received(1).GetAsync<List<Activity>>(new Uri("users/fake/received_events/public", UriKind.Relative), null, null);
} }
[Fact] [Fact]
@@ -159,7 +159,7 @@ namespace Octokit.Tests.Reactive
client.GetUserPerformed("fake"); client.GetUserPerformed("fake");
gitHubClient.Connection.GetAsync<IReadOnlyList<Activity>>(new Uri("users/fake/events", UriKind.Relative), null, null); gitHubClient.Connection.Received(1).GetAsync<List<Activity>>(new Uri("users/fake/events", UriKind.Relative), null, null);
} }
[Fact] [Fact]
@@ -183,7 +183,7 @@ namespace Octokit.Tests.Reactive
client.GetUserPerformedPublic("fake"); client.GetUserPerformedPublic("fake");
gitHubClient.Connection.GetAsync<IReadOnlyList<Activity>>(new Uri("users/fake/events/public", UriKind.Relative), null, null); gitHubClient.Connection.Received(1).GetAsync<List<Activity>>(new Uri("users/fake/events/public", UriKind.Relative), null, null);
} }
[Fact] [Fact]
@@ -207,7 +207,7 @@ namespace Octokit.Tests.Reactive
client.GetForAnOrganization("fake", "org"); client.GetForAnOrganization("fake", "org");
gitHubClient.Connection.GetAsync<IReadOnlyList<Activity>>(new Uri("users/fake/events/orgs/org", UriKind.Relative), null, null); gitHubClient.Connection.Received(1).GetAsync<List<Activity>>(new Uri("users/fake/events/orgs/org", UriKind.Relative), null, null);
} }
[Fact] [Fact]

View File

@@ -23,7 +23,7 @@ namespace Octokit.Tests.Reactive
client.GetAllForCurrent(); client.GetAllForCurrent();
githubClient.Connection.GetAsync<IReadOnlyList<User>>( githubClient.Connection.Received(1).GetAsync<List<User>>(
new Uri("user/followers", UriKind.Relative), null, null); new Uri("user/followers", UriKind.Relative), null, null);
} }
} }
@@ -38,7 +38,7 @@ namespace Octokit.Tests.Reactive
client.GetAll("alfhenrik"); client.GetAll("alfhenrik");
githubClient.Connection.GetAsync<IReadOnlyList<User>>( githubClient.Connection.Received(1).GetAsync<List<User>>(
new Uri("users/alfhenrik/followers", UriKind.Relative), null, null); new Uri("users/alfhenrik/followers", UriKind.Relative), null, null);
} }
@@ -62,7 +62,7 @@ namespace Octokit.Tests.Reactive
client.GetFollowingForCurrent(); client.GetFollowingForCurrent();
githubClient.Connection.GetAsync<IReadOnlyList<User>>( githubClient.Connection.Received(1).GetAsync<List<User>>(
new Uri("user/following", UriKind.Relative), null, null); new Uri("user/following", UriKind.Relative), null, null);
} }
} }
@@ -77,7 +77,7 @@ namespace Octokit.Tests.Reactive
client.GetFollowing("alfhenrik"); client.GetFollowing("alfhenrik");
githubClient.Connection.GetAsync<IReadOnlyList<User>>( githubClient.Connection.Received(1).GetAsync<List<User>>(
new Uri("users/alfhenrik/following", UriKind.Relative), null, null); new Uri("users/alfhenrik/following", UriKind.Relative), null, null);
} }

View File

@@ -47,7 +47,7 @@ namespace Octokit.Tests.Reactive
client.GetForRepository("fake", "repo"); client.GetForRepository("fake", "repo");
gitHubClient.Connection.GetAsync<IReadOnlyList<GitHubClient>>( gitHubClient.Connection.Received(1).GetAsync<List<IssueComment>>(
new Uri("repos/fake/repo/issues/comments", UriKind.Relative), null, null); new Uri("repos/fake/repo/issues/comments", UriKind.Relative), null, null);
} }
@@ -74,7 +74,7 @@ namespace Octokit.Tests.Reactive
client.GetForIssue("fake", "repo", 3); client.GetForIssue("fake", "repo", 3);
gitHubClient.Connection.GetAsync<IReadOnlyList<GitHubClient>>( gitHubClient.Connection.Received(1).GetAsync<List<IssueComment>>(
new Uri("repos/fake/repo/issues/3/comments", UriKind.Relative), null, null); new Uri("repos/fake/repo/issues/3/comments", UriKind.Relative), null, null);
} }

View File

@@ -295,21 +295,16 @@ using Xunit;
} }
[Fact] [Fact]
public async Task EnsuresArgumentsNotNull() public void EnsuresArgumentsNotNull()
{ {
var gitHubClient = Substitute.For<IGitHubClient>(); var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableIssuesClient(gitHubClient); var client = new ObservableIssuesClient(gitHubClient);
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", new NewIssue("title")));
client.Create(null, "name", new NewIssue("title"))); Assert.Throws<ArgumentException>(() => client.Create("", "name", new NewIssue("x")));
AssertEx.Throws<ArgumentException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, new NewIssue("x")));
client.Create("", "name", new NewIssue("x"))); Assert.Throws<ArgumentException>(() => client.Create("owner", "", new NewIssue("x")));
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
client.Create("owner", null, new NewIssue("x")));
AssertEx.Throws<ArgumentException>(async () => await
client.Create("owner", "", new NewIssue("x")));
AssertEx.Throws<ArgumentNullException>(async () => await
client.Create("owner", "name", null));
} }
} }
@@ -328,21 +323,16 @@ using Xunit;
} }
[Fact] [Fact]
public async Task EnsuresArgumentsNotNull() public void EnsuresArgumentsNotNull()
{ {
var gitHubClient = Substitute.For<IGitHubClient>(); var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableIssuesClient(gitHubClient); var client = new ObservableIssuesClient(gitHubClient);
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", new NewIssue("title")));
client.Create(null, "name", new NewIssue("title"))); Assert.Throws<ArgumentException>(() => client.Create("", "name", new NewIssue("x")));
AssertEx.Throws<ArgumentException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, new NewIssue("x")));
client.Create("", "name", new NewIssue("x"))); Assert.Throws<ArgumentException>(() => client.Create("owner", "", new NewIssue("x")));
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
client.Create("owner", null, new NewIssue("x")));
AssertEx.Throws<ArgumentException>(async () => await
client.Create("owner", "", new NewIssue("x")));
AssertEx.Throws<ArgumentNullException>(async () => await
client.Create("owner", "name", null));
} }
} }

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using NSubstitute; using NSubstitute;
using Octokit;
using Octokit.Internal; using Octokit.Internal;
using Octokit.Reactive; using Octokit.Reactive;
using Octokit.Tests.Helpers; using Octokit.Tests.Helpers;
@@ -166,21 +165,16 @@ namespace Octokit.Tests.Reactive
} }
[Fact] [Fact]
public async Task EnsuresArgumentsNotNull() public void EnsuresArgumentsNotNull()
{ {
var gitHubClient = Substitute.For<IGitHubClient>(); var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableMilestonesClient(gitHubClient); var client = new ObservableMilestonesClient(gitHubClient);
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", new NewMilestone("title")));
client.Create(null, "name", new NewMilestone("title"))); Assert.Throws<ArgumentException>(() => client.Create("", "name", new NewMilestone("x")));
AssertEx.Throws<ArgumentException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, new NewMilestone("x")));
client.Create("", "name", new NewMilestone("x"))); Assert.Throws<ArgumentException>(() => client.Create("owner", "", new NewMilestone("x")));
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
client.Create("owner", null, new NewMilestone("x")));
AssertEx.Throws<ArgumentException>(async () => await
client.Create("owner", "", new NewMilestone("x")));
AssertEx.Throws<ArgumentNullException>(async () => await
client.Create("owner", "name", null));
} }
} }
@@ -199,21 +193,16 @@ namespace Octokit.Tests.Reactive
} }
[Fact] [Fact]
public async Task EnsuresArgumentsNotNull() public void EnsuresArgumentsNotNull()
{ {
var gitHubClient = Substitute.For<IGitHubClient>(); var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableMilestonesClient(gitHubClient); var client = new ObservableMilestonesClient(gitHubClient);
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", new NewMilestone("title")));
client.Create(null, "name", new NewMilestone("title"))); Assert.Throws<ArgumentException>(() => client.Create("", "name", new NewMilestone("x")));
AssertEx.Throws<ArgumentException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, new NewMilestone("x")));
client.Create("", "name", new NewMilestone("x"))); Assert.Throws<ArgumentException>(() => client.Create("owner", "", new NewMilestone("x")));
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
client.Create("owner", null, new NewMilestone("x")));
AssertEx.Throws<ArgumentException>(async () => await
client.Create("owner", "", new NewMilestone("x")));
AssertEx.Throws<ArgumentNullException>(async () => await
client.Create("owner", "name", null));
} }
} }
@@ -231,19 +220,15 @@ namespace Octokit.Tests.Reactive
} }
[Fact] [Fact]
public async Task EnsuresArgumentsNotNull() public void EnsuresArgumentsNotNull()
{ {
var gitHubClient = Substitute.For<IGitHubClient>(); var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableMilestonesClient(gitHubClient); var client = new ObservableMilestonesClient(gitHubClient);
AssertEx.Throws<ArgumentNullException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Delete(null, "name", 42));
client.Delete(null, "name", 42)); Assert.Throws<ArgumentException>(() => client.Delete("", "name", 42));
AssertEx.Throws<ArgumentException>(async () => await Assert.Throws<ArgumentNullException>(() => client.Delete("owner", null, 42));
client.Delete("", "name", 42)); Assert.Throws<ArgumentException>(() => client.Delete("owner", "", 42));
AssertEx.Throws<ArgumentNullException>(async () => await
client.Delete("owner", null, 42));
AssertEx.Throws<ArgumentException>(async () => await
client.Delete("owner", "", 42));
} }
} }

View File

@@ -23,7 +23,7 @@ namespace Octokit.Tests.Reactive
client.GetAll("org"); client.GetAll("org");
gitHubClient.Connection.GetAsync<IReadOnlyList<User>>( gitHubClient.Connection.Received(1).GetAsync<List<User>>(
new Uri("orgs/org/members", UriKind.Relative), null, null); new Uri("orgs/org/members", UriKind.Relative), null, null);
} }
@@ -47,7 +47,7 @@ namespace Octokit.Tests.Reactive
client.GetPublic("org"); client.GetPublic("org");
gitHubClient.Connection.GetAsync<IReadOnlyList<User>>( gitHubClient.Connection.Received(1).GetAsync<List<User>>(
new Uri("orgs/org/public_members", UriKind.Relative), null, null); new Uri("orgs/org/public_members", UriKind.Relative), null, null);
} }

View File

@@ -0,0 +1,286 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reactive.Linq;
using System.Threading.Tasks;
using NSubstitute;
using Octokit.Reactive;
using Octokit.Tests.Helpers;
using Xunit;
namespace Octokit.Tests.Reactive
{
public class ObservableReleasesClientTests
{
public class TheCtorMethod
{
[Fact]
public void EnsuresArgumentIsNotNull()
{
Assert.Throws<ArgumentNullException>(() => new ObservableReleasesClient(null));
}
}
public class TheGetReleasesMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableReleasesClient(gitHubClient);
client.GetAll("fake", "repo");
gitHubClient.Connection.Received(1).GetAsync<List<Release>>(
new Uri("repos/fake/repo/releases", UriKind.Relative), null, null);
}
[Fact]
public void EnsuresNonNullArguments()
{
var releasesClient = new ObservableReleasesClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => releasesClient.GetAll(null, "name"));
Assert.Throws<ArgumentNullException>(() => releasesClient.GetAll("owner", null));
}
}
public class TheGetReleaseMethod
{
[Fact]
public void CallsIntoClient()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableReleasesClient(gitHubClient);
client.Get("fake", "repo", 1);
gitHubClient.Release.Received(1).Get("fake", "repo", 1);
}
[Fact]
public void EnsuresNonNullArguments()
{
var releasesClient = new ObservableReleasesClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => releasesClient.Get(null, "name", 1));
Assert.Throws<ArgumentException>(() => releasesClient.Get("", "name", 1));
Assert.Throws<ArgumentNullException>(() => releasesClient.Get("owner", null, 1));
Assert.Throws<ArgumentException>(() => releasesClient.Get("owner", "", 1));
}
}
public class TheCreateReleaseMethod
{
[Fact]
public void CallsIntoClient()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var releasesClient = new ObservableReleasesClient(gitHubClient);
var data = new ReleaseUpdate("fake-tag");
releasesClient.CreateRelease("fake", "repo", data);
gitHubClient.Release.Received(1).CreateRelease("fake", "repo", data);
}
[Fact]
public void EnsuresArgumentsNotNull()
{
var releasesClient = new ObservableReleasesClient(Substitute.For<IGitHubClient>());
var data = new ReleaseUpdate("fake-tag");
Assert.Throws<ArgumentNullException>(() => new ReleaseUpdate(null));
Assert.Throws<ArgumentNullException>(() => releasesClient.CreateRelease(null, "name", data));
Assert.Throws<ArgumentNullException>(() => releasesClient.CreateRelease("owner", null, data));
Assert.Throws<ArgumentNullException>(() => releasesClient.CreateRelease("owner", "name", null));
}
}
public class TheEditReleaseMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var releasesClient = new ObservableReleasesClient(gitHubClient);
var data = new ReleaseUpdate("fake-tag");
releasesClient.EditRelease("fake", "repo", data);
gitHubClient.Release.Received(1).EditRelease("fake", "repo", data);
}
[Fact]
public void EnsuresNonNullArguments()
{
var releasesClient = new ObservableReleasesClient(Substitute.For<IGitHubClient>());
var update = new ReleaseUpdate("tag");
Assert.Throws<ArgumentNullException>(() => releasesClient.EditRelease(null, "name", update));
Assert.Throws<ArgumentException>(() => releasesClient.EditRelease("", "name", update));
Assert.Throws<ArgumentNullException>(() => releasesClient.EditRelease("owner", null, update));
Assert.Throws<ArgumentException>(() => releasesClient.EditRelease("owner", "", update));
Assert.Throws<ArgumentNullException>(() => releasesClient.EditRelease("owner", "name", null));
}
}
public class TheDeleteReleaseMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableReleasesClient(gitHubClient);
client.DeleteRelease("fake", "repo", 1);
gitHubClient.Release.Received(1).DeleteRelease("fake", "repo", 1);
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ObservableReleasesClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => client.DeleteRelease(null, "name", 1));
Assert.Throws<ArgumentException>(() => client.DeleteRelease("", "name", 1));
Assert.Throws<ArgumentNullException>(() => client.DeleteRelease("owner", null, 1));
Assert.Throws<ArgumentException>(() => client.DeleteRelease("owner", "", 1));
}
}
public class TheGetAssetsMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableReleasesClient(gitHubClient);
client.GetAssets("fake", "repo", 1);
gitHubClient.Connection.Received(1).GetAsync<List<ReleaseAsset>>(
new Uri("repos/fake/repo/releases/1/assets", UriKind.Relative), null, null);
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ObservableReleasesClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => client.GetAssets(null, "name", 1));
Assert.Throws<ArgumentException>(() => client.GetAssets("", "name", 1));
Assert.Throws<ArgumentNullException>(() => client.GetAssets("owner", null, 1));
Assert.Throws<ArgumentException>(() => client.GetAssets("owner", "", 1));
}
}
public class TheUploadReleaseAssetMethod
{
[Fact]
public void CallsIntoClient()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var releasesClient = new ObservableReleasesClient(gitHubClient);
var release = new Release { UploadUrl = "https://uploads.test.dev/does/not/matter/releases/1/assets{?name}" };
var rawData = Substitute.For<Stream>();
var upload = new ReleaseAssetUpload { FileName = "example.zip", ContentType = "application/zip", RawData = rawData };
releasesClient.UploadAsset(release, upload);
gitHubClient.Release.Received(1).UploadAsset(release, upload);
}
[Fact]
public void EnsuresArgumentsNotNull()
{
var releasesClient = new ObservableReleasesClient(Substitute.For<IGitHubClient>());
var release = new Release { UploadUrl = "https://uploads.github.com/anything" };
var uploadData = new ReleaseAssetUpload { FileName = "good", ContentType = "good/good", RawData = Stream.Null };
Assert.Throws<ArgumentNullException>(() => releasesClient.UploadAsset(null, uploadData));
Assert.Throws<ArgumentNullException>(() => releasesClient.UploadAsset(release, null));
}
}
public class TheGetAssetMethod
{
[Fact]
public void CallsIntoClient()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableReleasesClient(gitHubClient);
client.GetAsset("fake", "repo", 1, 1);
gitHubClient.Release.Received(1).GetAsset("fake", "repo", 1, 1);
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ObservableReleasesClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => client.GetAsset(null, "name", 1, 1));
Assert.Throws<ArgumentException>(() => client.GetAsset("", "name", 1, 1));
Assert.Throws<ArgumentNullException>(() => client.GetAsset("owner", null, 1, 1));
Assert.Throws<ArgumentException>(() => client.GetAsset("owner", "", 1, 1));
}
}
public class TheEditAssetMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableReleasesClient(gitHubClient);
var data = new ReleaseAssetUpdate("asset");
client.EditAsset("fake", "repo", 1, 1, data);
gitHubClient.Release.Received(1).EditAsset("fake", "repo", 1, 1, data);
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ObservableReleasesClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => client.EditAsset(null, "name", 1, 1, new ReleaseAssetUpdate("name")));
Assert.Throws<ArgumentException>(() => client.EditAsset("", "name", 1, 1, new ReleaseAssetUpdate("name")));
Assert.Throws<ArgumentNullException>(() => client.EditAsset("owner", null, 1, 1, new ReleaseAssetUpdate("name")));
Assert.Throws<ArgumentException>(() => client.EditAsset("owner", "", 1, 1, new ReleaseAssetUpdate("name")));
Assert.Throws<ArgumentNullException>(() => client.EditAsset("owner", "name", 1, 1, null));
}
}
public class TheDeleteAssetMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableReleasesClient(gitHubClient);
client.DeleteAsset("fake", "repo", 1);
gitHubClient.Connection.DeleteAsync(
new Uri("repos/fake/repo/releases/assets/1", UriKind.Relative));
}
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ObservableReleasesClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => client.DeleteAsset(null, "name", 1));
Assert.Throws<ArgumentException>(() => client.DeleteAsset("", "name", 1));
Assert.Throws<ArgumentNullException>(() => client.DeleteAsset("owner", null, 1));
Assert.Throws<ArgumentException>(() => client.DeleteAsset("owner", "", 1));
}
}
}
}

View File

@@ -162,6 +162,202 @@ namespace Octokit.Tests.Reactive
} }
} }
public class TheGetAllBranchesMethod
{
[Fact]
public void EnsuresArguments()
{
var client = new ObservableRepositoriesClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => client.GetAllBranches(null, "repo"));
Assert.Throws<ArgumentNullException>(() => client.GetAllBranches("owner", null));
Assert.Throws<ArgumentException>(() => client.GetAllBranches("", "repo"));
Assert.Throws<ArgumentException>(() => client.GetAllBranches("owner", ""));
}
[Fact]
public void GetsCorrectUrl()
{
var github = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoriesClient(github);
var expected = new Uri("repos/owner/repo/branches", UriKind.Relative);
client.GetAllBranches("owner", "repo");
github.Connection.Received(1).GetAsync<List<Branch>>(expected);
}
}
public class TheGetAllContributorsMethod
{
[Fact]
public void EnsuresArguments()
{
var client = new ObservableRepositoriesClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => client.GetAllContributors(null, "repo"));
Assert.Throws<ArgumentNullException>(() => client.GetAllContributors("owner", null));
Assert.Throws<ArgumentException>(() => client.GetAllContributors("", "repo"));
Assert.Throws<ArgumentException>(() => client.GetAllContributors("owner", ""));
}
[Fact]
public void GetsCorrectUrl()
{
var github = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoriesClient(github);
var expected = new Uri("repos/owner/repo/contributors", UriKind.Relative);
client.GetAllContributors("owner", "repo");
github.Connection.Received(1)
.GetAsync<List<User>>(expected,
Arg.Any<IDictionary<string, string>>(),
Arg.Any<string>());
}
// TODO: Needs test for 'includeAnonymous'
}
public class TheGetAllLanguagesMethod
{
[Fact]
public void EnsuresNonNullArguments()
{
var client = new ObservableRepositoriesClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => client.GetAllLanguages(null, "repo"));
Assert.Throws<ArgumentNullException>(() => client.GetAllLanguages("owner", null));
Assert.Throws<ArgumentException>(() => client.GetAllLanguages("", "repo"));
Assert.Throws<ArgumentException>(() => client.GetAllLanguages("owner", ""));
}
[Fact]
public void GetsCorrectUrl()
{
var github = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoriesClient(github);
var expected = new Uri("repos/owner/repo/languages", UriKind.Relative);
client.GetAllLanguages("owner", "repo");
github.Connection.Received(1).GetAsync<List<Tuple<string, long>>>(expected);
}
}
public class TheGetAllTeamsMethod
{
[Fact]
public void EnsuresArguments()
{
var client = new ObservableRepositoriesClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => client.GetAllTeams(null, "repo"));
Assert.Throws<ArgumentNullException>(() => client.GetAllTeams("owner", null));
Assert.Throws<ArgumentException>(() => client.GetAllTeams("", "repo"));
Assert.Throws<ArgumentException>(() => client.GetAllTeams("owner", ""));
}
[Fact]
public void GetsCorrectUrl()
{
var github = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoriesClient(github);
var expected = new Uri("repos/owner/repo/teams", UriKind.Relative);
client.GetAllTeams("owner", "repo");
github.Connection.Received(1).GetAsync<List<Team>>(expected);
}
}
public class TheGetAllTagsMethod
{
[Fact]
public void EnsuresArguments()
{
var client = new ObservableRepositoriesClient(Substitute.For<IGitHubClient>());
Assert.Throws<ArgumentNullException>(() => client.GetAllTags(null, "repo"));
Assert.Throws<ArgumentNullException>(() => client.GetAllTags("owner", null));
Assert.Throws<ArgumentException>(() => client.GetAllTags("", "repo"));
Assert.Throws<ArgumentException>(() => client.GetAllTags("owner", ""));
}
[Fact]
public void GetsCorrectUrl()
{
var github = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoriesClient(github);
var expected = new Uri("repos/owner/repo/tags", UriKind.Relative);
client.GetAllTags("owner", "repo");
github.Connection.Received(1).GetAsync<List<RepositoryTag>>(expected);
}
}
public class TheGetBranchMethod
{
[Fact]
public async Task EnsuresArguments()
{
var github = Substitute.For<IGitHubClient>();
var nonreactiveClient = new RepositoriesClient(Substitute.For<IApiConnection>());
github.Repository.Returns(nonreactiveClient);
var client = new ObservableRepositoriesClient(github);
Assert.Throws<ArgumentNullException>(() => client.GetBranch(null, "repo", "branch"));
Assert.Throws<ArgumentNullException>(() => client.GetBranch("owner", null, "branch"));
Assert.Throws<ArgumentNullException>(() => client.GetBranch("owner", "repo", null));
Assert.Throws<ArgumentException>(() => client.GetBranch("", "repo", "branch"));
Assert.Throws<ArgumentException>(() => client.GetBranch("owner", "", "branch"));
Assert.Throws<ArgumentException>(() => client.GetBranch("owner", "repo", ""));
}
[Fact]
public void CallsIntoClient()
{
var github = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoriesClient(github);
client.GetBranch("owner", "repo", "branch");
github.Repository.Received(1).GetBranch("owner", "repo", "branch");
}
}
public class TheEditMethod
{
[Fact]
public async Task EnsuresArguments()
{
var github = Substitute.For<IGitHubClient>();
var nonreactiveClient = new RepositoriesClient(Substitute.For<IApiConnection>());
github.Repository.Returns(nonreactiveClient);
var client = new ObservableRepositoriesClient(github);
var update = new RepositoryUpdate();
Assert.Throws<ArgumentNullException>(() => client.Edit(null, "repo", update));
Assert.Throws<ArgumentNullException>(() => client.Edit("owner", null, update));
Assert.Throws<ArgumentNullException>(() => client.Edit("owner", "repo", null));
Assert.Throws<ArgumentException>(() => client.Edit("", "repo", update));
Assert.Throws<ArgumentException>(() => client.Edit("owner", "", update));
}
[Fact]
public void CallsIntoClient()
{
var github = Substitute.For<IGitHubClient>();
var client = new ObservableRepositoriesClient(github);
var update = new RepositoryUpdate();
client.Edit("owner", "repo", update);
github.Repository.Received(1).Edit("owner", "repo", update);
}
}
static ApiInfo CreateApiInfo(IDictionary<string, Uri> links) static ApiInfo CreateApiInfo(IDictionary<string, Uri> links)
{ {
return new ApiInfo(links, new List<string>(), new List<string>(), "etag", new RateLimit(new Dictionary<string, string>())); return new ApiInfo(links, new List<string>(), new List<string>(), "etag", new RateLimit(new Dictionary<string, string>()));

View File

@@ -0,0 +1,41 @@
using System;
using System.Reactive.Linq;
using System.Threading.Tasks;
using NSubstitute;
using Octokit.Reactive;
using Octokit.Tests.Helpers;
using Xunit;
namespace Octokit.Tests.Reactive
{
public class ObservableStatisticsClientTests
{
public class TheGetMethod
{
[Fact]
public void GetsFromClientIssueMilestone()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var statisticsClient = new ObservableStatisticsClient(gitHubClient);
statisticsClient.GetContributors("username", "repositoryName");
gitHubClient.Statistics.Received().GetContributors("username", "repositoryName");
}
[Fact]
public async Task ThrowsIfGivenNullRepositoryName()
{
var statisticsClient = new ObservableStatisticsClient(Substitute.For<IGitHubClient>());
await AssertEx.Throws<ArgumentNullException>(async () => await statisticsClient.GetContributors("owner", null));
}
[Fact]
public async Task ThrowsIfGivenNullOwnerName()
{
var statisticsClient = new ObservableStatisticsClient(Substitute.For<IGitHubClient>());
await AssertEx.Throws<ArgumentNullException>(async () => await statisticsClient.GetContributors(null, "repositoryName"));
}
}
}
}

View File

@@ -57,11 +57,11 @@ namespace Octokit.Tests
var gitHubClient = Substitute.For<IGitHubClient>(); var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableTreesClient(gitHubClient); var client = new ObservableTreesClient(gitHubClient);
AssertEx.Throws<ArgumentNullException>(async () => await client.Create(null, "name", new NewTree())); Assert.Throws<ArgumentNullException>(() => client.Create(null, "name", new NewTree()));
AssertEx.Throws<ArgumentException>(async () => await client.Create("", "name", new NewTree())); Assert.Throws<ArgumentException>(() => client.Create("", "name", new NewTree()));
AssertEx.Throws<ArgumentNullException>(async () => await client.Create("owner", null, new NewTree())); Assert.Throws<ArgumentNullException>(() => client.Create("owner", null, new NewTree()));
AssertEx.Throws<ArgumentException>(async () => await client.Create("owner", "", new NewTree())); Assert.Throws<ArgumentException>(() => client.Create("owner", "", new NewTree()));
AssertEx.Throws<ArgumentNullException>(async () => await client.Create("owner", "name", null)); Assert.Throws<ArgumentNullException>(() => client.Create("owner", "name", null));
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show More