Skip to content

Commit

Permalink
Add ability to specify 'since' request parameter to issue comments (#…
Browse files Browse the repository at this point in the history
…2008)

* Update issue comments client to allow returning comments 'since' a specific date

* Update observable issue comments client to allow returning comments 'since' a specific date

* Add test cases to cover newly added methods
  • Loading branch information
hnrkndrssn authored and shiftkey committed Sep 21, 2019
1 parent 63a4dea commit 9e5a768
Show file tree
Hide file tree
Showing 6 changed files with 316 additions and 12 deletions.
40 changes: 40 additions & 0 deletions Octokit.Reactive/Clients/IObservableIssueCommentsClient.cs
Expand Up @@ -137,6 +137,46 @@ public interface IObservableIssueCommentsClient
/// <param name="options">Options for changing the API response</param>
IObservable<IssueComment> GetAllForIssue(long repositoryId, int number, ApiOptions options);

/// <summary>
/// Gets Issue Comments for a specified Issue.
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="request">The sorting <see cref="IssueCommentRequest">parameters</see></param>
IObservable<IssueComment> GetAllForIssue(string owner, string name, int number, IssueCommentRequest request);

/// <summary>
/// Gets Issue Comments for a specified Issue.
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="request">The sorting <see cref="IssueCommentRequest">parameters</see></param>
IObservable<IssueComment> GetAllForIssue(long repositoryId, int number, IssueCommentRequest request);

/// <summary>
/// Gets Issue Comments for a specified Issue.
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="request">The sorting <see cref="IssueCommentRequest">parameters</see></param>
/// <param name="options">Options for changing the API response</param>
IObservable<IssueComment> GetAllForIssue(string owner, string name, int number, IssueCommentRequest request, ApiOptions options);

/// <summary>
/// Gets Issue Comments for a specified Issue.
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="request">The sorting <see cref="IssueCommentRequest">parameters</see></param>
/// <param name="options">Options for changing the API response</param>
IObservable<IssueComment> GetAllForIssue(long repositoryId, int number, IssueCommentRequest request, ApiOptions options);

/// <summary>
/// Creates a new Issue Comment for a specified Issue.
/// </summary>
Expand Down
71 changes: 69 additions & 2 deletions Octokit.Reactive/Clients/ObservableIssueCommentsClient.cs
Expand Up @@ -205,7 +205,7 @@ public IObservable<IssueComment> GetAllForIssue(string owner, string name, int n
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNull(options, nameof(options));

return _connection.GetAndFlattenAllPages<IssueComment>(ApiUrls.IssueComments(owner, name, number), null, AcceptHeaders.ReactionsPreview, options);
return GetAllForIssue(owner, name, number, new IssueCommentRequest(), options);
}

/// <summary>
Expand All @@ -219,7 +219,74 @@ public IObservable<IssueComment> GetAllForIssue(long repositoryId, int number, A
{
Ensure.ArgumentNotNull(options, nameof(options));

return _connection.GetAndFlattenAllPages<IssueComment>(ApiUrls.IssueComments(repositoryId, number), options);
return GetAllForIssue(repositoryId, number, new IssueCommentRequest(), options);
}

/// <summary>
/// Gets Issue Comments for a specified Issue.
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="request">The sorting <see cref="IssueCommentRequest">parameters</see></param>
public IObservable<IssueComment> GetAllForIssue(string owner, string name, int number, IssueCommentRequest request)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNull(request, nameof(request));

return GetAllForIssue(owner, name, number, request, ApiOptions.None);
}

/// <summary>
/// Gets Issue Comments for a specified Issue.
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="request">The sorting <see cref="IssueCommentRequest">parameters</see></param>
public IObservable<IssueComment> GetAllForIssue(long repositoryId, int number, IssueCommentRequest request)
{
Ensure.ArgumentNotNull(request, nameof(request));

return GetAllForIssue(repositoryId, number, request, ApiOptions.None);
}

/// <summary>
/// Gets Issue Comments for a specified Issue.
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="request">The sorting <see cref="IssueCommentRequest">parameters</see></param>
/// <param name="options">Options for changing the API response</param>
public IObservable<IssueComment> GetAllForIssue(string owner, string name, int number, IssueCommentRequest request, ApiOptions options)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNull(request, nameof(request));
Ensure.ArgumentNotNull(options, nameof(options));

return _connection.GetAndFlattenAllPages<IssueComment>(ApiUrls.IssueComments(owner, name, number), request.ToParametersDictionary(), AcceptHeaders.ReactionsPreview, options);

}

/// <summary>
/// Gets Issue Comments for a specified Issue.
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="request">The sorting <see cref="IssueCommentRequest">parameters</see></param>
/// <param name="options">Options for changing the API response</param>
public IObservable<IssueComment> GetAllForIssue(long repositoryId, int number, IssueCommentRequest request, ApiOptions options)
{
Ensure.ArgumentNotNull(request, nameof(request));
Ensure.ArgumentNotNull(options, nameof(options));

return _connection.GetAndFlattenAllPages<IssueComment>(ApiUrls.IssueComments(repositoryId, number), request.ToParametersDictionary(), AcceptHeaders.ReactionsPreview, options);
}

/// <summary>
Expand Down
47 changes: 45 additions & 2 deletions Octokit.Tests/Clients/IssueCommentsClientTests.cs
Expand Up @@ -180,6 +180,45 @@ public async Task RequestsCorrectUrlWithRepositoryId()
Args.ApiOptions);
}

[Fact]
public async Task RequestsCorrectUrlWithIssueCommentRequest()
{
var connection = Substitute.For<IApiConnection>();
var client = new IssueCommentsClient(connection);

var request = new IssueCommentRequest()
{
Since = new DateTimeOffset(2016, 11, 23, 11, 11, 11, 00, new TimeSpan()),
};

await client.GetAllForIssue("fake", "repo", 3, request);

connection.Received().GetAll<IssueComment>(
Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/issues/3/comments"),
Arg.Any<Dictionary<string, string>>(),
"application/vnd.github.squirrel-girl-preview",
Args.ApiOptions);
}

[Fact]
public async Task RequestsCorrectUrlWithRepositoryIdWithIssueCommentRequest()
{
var connection = Substitute.For<IApiConnection>();
var client = new IssueCommentsClient(connection);

var request = new IssueCommentRequest()
{
Since = new DateTimeOffset(2016, 11, 23, 11, 11, 11, 00, new TimeSpan()),
};

await client.GetAllForIssue(1, 3, request);

connection.Received().GetAll<IssueComment>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/issues/3/comments"),
Arg.Any<Dictionary<string, string>>(),
"application/vnd.github.squirrel-girl-preview",
Args.ApiOptions);
}

[Fact]
public async Task RequestsCorrectUrlWithApiOptions()
{
Expand Down Expand Up @@ -233,9 +272,13 @@ public async Task EnsuresNonNullArguments()
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForIssue("owner", null, 1));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForIssue(null, "name", 1, ApiOptions.None));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForIssue("owner", null, 1, ApiOptions.None));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForIssue("owner", "name", 1, null));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForIssue("owner", "name", 1, options: null));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForIssue("owner", "name", 1, request: null));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForIssue("owner", "name", 1, null, ApiOptions.None));

await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForIssue(1, 1, null));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForIssue(1, 1, options: null));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForIssue(1, 1, request: null));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAllForIssue(1, 1, null, ApiOptions.None));

await Assert.ThrowsAsync<ArgumentException>(() => client.GetAllForIssue("", "name", 1));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetAllForIssue("owner", "", 1));
Expand Down
60 changes: 54 additions & 6 deletions Octokit.Tests/Reactive/ObservableIssueCommentsClientTests.cs
Expand Up @@ -171,7 +171,7 @@ public void RequestsCorrectUrl()

gitHubClient.Connection.Received(1).Get<List<IssueComment>>(
new Uri("repos/fake/repo/issues/3/comments", UriKind.Relative),
Args.EmptyDictionary,
Arg.Any<IDictionary<string, string>>(),
"application/vnd.github.squirrel-girl-preview");
}

Expand All @@ -184,7 +184,47 @@ public void RequestsCorrectUrlWithRepositoryId()
client.GetAllForIssue(1, 3);

gitHubClient.Connection.Received(1).Get<List<IssueComment>>(
new Uri("repositories/1/issues/3/comments", UriKind.Relative), Args.EmptyDictionary, null);
new Uri("repositories/1/issues/3/comments", UriKind.Relative), Arg.Any<IDictionary<string, string>>(), "application/vnd.github.squirrel-girl-preview");
}

[Fact]
public void RequestsCorrectUrlWithIssueCommentRequest()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableIssueCommentsClient(gitHubClient);

var request = new IssueCommentRequest()
{
Since = new DateTimeOffset(2016, 11, 23, 11, 11, 11, 00, new TimeSpan()),
};

client.GetAllForIssue("fake", "repo", 3, request);

gitHubClient.Connection.Received(1).Get<List<IssueComment>>(
new Uri("repos/fake/repo/issues/3/comments", UriKind.Relative),
Arg.Is<IDictionary<string, string>>(d => d.Count == 3
&& d["since"] == "2016-11-23T11:11:11Z"),
"application/vnd.github.squirrel-girl-preview");
}

[Fact]
public void RequestsCorrectUrlWithRepositoryIdWithIssueCommentRequest()
{
var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableIssueCommentsClient(gitHubClient);

var request = new IssueCommentRequest()
{
Since = new DateTimeOffset(2016, 11, 23, 11, 11, 11, 00, new TimeSpan()),
};

client.GetAllForIssue(1, 3, request);

gitHubClient.Connection.Received(1).Get<List<IssueComment>>(
new Uri("repositories/1/issues/3/comments", UriKind.Relative),
Arg.Is<Dictionary<string, string>>(d => d.Count == 3
&& d["since"] == "2016-11-23T11:11:11Z"),
"application/vnd.github.squirrel-girl-preview");
}

[Fact]
Expand All @@ -203,7 +243,9 @@ public void RequestsCorrectUrlWithApiOptions()
client.GetAllForIssue("fake", "repo", 3, options);

gitHubClient.Connection.Received(1).Get<List<IssueComment>>(
new Uri("repos/fake/repo/issues/3/comments", UriKind.Relative), Arg.Is<IDictionary<string, string>>(d => d.Count == 2), "application/vnd.github.squirrel-girl-preview");
new Uri("repos/fake/repo/issues/3/comments", UriKind.Relative),
Arg.Is<IDictionary<string, string>>(d => d.Count == 4),
"application/vnd.github.squirrel-girl-preview");
}

[Fact]
Expand All @@ -222,7 +264,9 @@ public void RequestsCorrectUrlWithRepositoryIdWithApiOptions()
client.GetAllForIssue(1, 3, options);

gitHubClient.Connection.Received(1).Get<List<IssueComment>>(
new Uri("repositories/1/issues/3/comments", UriKind.Relative), Arg.Is<IDictionary<string, string>>(d => d.Count == 2), null);
new Uri("repositories/1/issues/3/comments", UriKind.Relative),
Arg.Is<Dictionary<string, string>>(d => d.Count == 4),
"application/vnd.github.squirrel-girl-preview");
}

[Fact]
Expand All @@ -235,9 +279,13 @@ public async Task EnsuresNonNullArguments()
Assert.Throws<ArgumentNullException>(() => client.GetAllForIssue("owner", null, 1));
Assert.Throws<ArgumentNullException>(() => client.GetAllForIssue(null, "name", 1, ApiOptions.None));
Assert.Throws<ArgumentNullException>(() => client.GetAllForIssue("owner", null, 1, ApiOptions.None));
Assert.Throws<ArgumentNullException>(() => client.GetAllForIssue("owner", "name", 1, null));
Assert.Throws<ArgumentNullException>(() => client.GetAllForIssue("owner", "name", 1, options: null));
Assert.Throws<ArgumentNullException>(() => client.GetAllForIssue("owner", "name", 1, request: null));
Assert.Throws<ArgumentNullException>(() => client.GetAllForIssue("owner", "name", 1, null, ApiOptions.None));

Assert.Throws<ArgumentNullException>(() => client.GetAllForIssue(1, 1, null));
Assert.Throws<ArgumentNullException>(() => client.GetAllForIssue(1, 1, options: null));
Assert.Throws<ArgumentNullException>(() => client.GetAllForIssue(1, 1, request: null));
Assert.Throws<ArgumentNullException>(() => client.GetAllForIssue(1, 1, null, ApiOptions.None));

Assert.Throws<ArgumentException>(() => client.GetAllForIssue("", "name", 1));
Assert.Throws<ArgumentException>(() => client.GetAllForIssue("owner", "", 1));
Expand Down
40 changes: 40 additions & 0 deletions Octokit/Clients/IIssueCommentsClient.cs
Expand Up @@ -137,6 +137,46 @@ public interface IIssueCommentsClient
/// <param name="options">Options for changing the API response</param>
Task<IReadOnlyList<IssueComment>> GetAllForIssue(long repositoryId, int number, ApiOptions options);

/// <summary>
/// Gets Issue Comments for a specified Issue.
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="request">The sorting <see cref="IssueCommentRequest">parameters</see></param>
Task<IReadOnlyList<IssueComment>> GetAllForIssue(string owner, string name, int number, IssueCommentRequest request);

/// <summary>
/// Gets Issue Comments for a specified Issue.
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="request">The sorting <see cref="IssueCommentRequest">parameters</see></param>
Task<IReadOnlyList<IssueComment>> GetAllForIssue(long repositoryId, int number, IssueCommentRequest request);

/// <summary>
/// Gets Issue Comments for a specified Issue.
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue</remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="request">The sorting <see cref="IssueCommentRequest">parameters</see></param>
/// <param name="options">Options for changing the API response</param>
Task<IReadOnlyList<IssueComment>> GetAllForIssue(string owner, string name, int number, IssueCommentRequest request, ApiOptions options);

/// <summary>
/// Gets Issue Comments for a specified Issue.
/// </summary>
/// <remarks>http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="request">The sorting <see cref="IssueCommentRequest">parameters</see></param>
/// <param name="options">Options for changing the API response</param>
Task<IReadOnlyList<IssueComment>> GetAllForIssue(long repositoryId, int number, IssueCommentRequest request, ApiOptions options);

/// <summary>
/// Creates a new Issue Comment for a specified Issue.
/// </summary>
Expand Down

0 comments on commit 9e5a768

Please sign in to comment.