add active lock reason to PR (#2543)

* add active lock reason to PR

* update docs

* refactor: extract lock and unlock from IIssuesClient
create ILockUnlockClient so both IIssuesClient and IPullRequestClient can
access lock and unlock methods.

* refactor LockUnlock for reactive clients

* Update doc to include lock unlock sample code

* Use Assert.Null to check null value in test

Co-authored-by: notauserx <notauserx@users.noreply.github.com>
This commit is contained in:
notauserx
2022-08-19 23:36:47 +06:00
committed by GitHub
parent b866d669d6
commit 595e35d641
20 changed files with 405 additions and 255 deletions

View File

@@ -44,6 +44,11 @@ namespace Octokit.Reactive
/// </summary> /// </summary>
IObservableIssueTimelineClient Timeline { get; } IObservableIssueTimelineClient Timeline { get; }
/// <summary>
/// Client for locking/unlocking conversation on an issue
/// </summary>
IObservableLockUnlockClient LockUnlock { get; }
/// <summary> /// <summary>
/// Gets a single Issue by number. /// Gets a single Issue by number.
/// </summary> /// </summary>
@@ -316,41 +321,5 @@ namespace Octokit.Reactive
/// <param name="issueUpdate">An <see cref="IssueUpdate"/> instance describing the changes to make to the issue /// <param name="issueUpdate">An <see cref="IssueUpdate"/> instance describing the changes to make to the issue
/// </param> /// </param>
IObservable<Issue> Update(long repositoryId, int number, IssueUpdate issueUpdate); IObservable<Issue> Update(long repositoryId, int number, IssueUpdate issueUpdate);
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-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="lockReason">The reason for locking the issue</param>
IObservable<Unit> Lock(string owner, string name, int number, LockReason? lockReason = null);
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="lockReason">The reason for locking the issue</param>
IObservable<Unit> Lock(long repositoryId, int number, LockReason? lockReason = null);
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-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>
IObservable<Unit> Unlock(string owner, string name, int number);
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
IObservable<Unit> Unlock(long repositoryId, int number);
} }
} }

View File

@@ -0,0 +1,47 @@
using System;
using System.Reactive;
namespace Octokit.Reactive
{
/// <summary>
/// Client to manage locking/unlocking a conversation for an Issue or a Pull request
/// </summary>
public interface IObservableLockUnlockClient
{
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-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="lockReason">The reason for locking the issue</param>
IObservable<Unit> Lock(string owner, string name, int number, LockReason? lockReason = null);
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="lockReason">The reason for locking the issue</param>
IObservable<Unit> Lock(long repositoryId, int number, LockReason? lockReason = null);
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-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>
IObservable<Unit> Unlock(string owner, string name, int number);
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
IObservable<Unit> Unlock(long repositoryId, int number);
}
}

View File

@@ -26,6 +26,11 @@ namespace Octokit.Reactive
/// </summary> /// </summary>
IObservablePullRequestReviewRequestsClient ReviewRequest { get; } IObservablePullRequestReviewRequestsClient ReviewRequest { get; }
/// <summary>
/// Client for locking/unlocking a conversation on a pull request
/// </summary>
IObservableLockUnlockClient LockUnlock { get; }
/// <summary> /// <summary>
/// Gets a single Pull Request by number. /// Gets a single Pull Request by number.
/// </summary> /// </summary>

View File

@@ -48,6 +48,11 @@ namespace Octokit.Reactive
/// </summary> /// </summary>
public IObservableIssueTimelineClient Timeline { get; private set; } public IObservableIssueTimelineClient Timeline { get; private set; }
/// <summary>
/// Client for locking/unlocking conversation on an issue
/// </summary>
public IObservableLockUnlockClient LockUnlock { get; protected set; }
public ObservableIssuesClient(IGitHubClient client) public ObservableIssuesClient(IGitHubClient client)
{ {
Ensure.ArgumentNotNull(client, nameof(client)); Ensure.ArgumentNotNull(client, nameof(client));
@@ -60,6 +65,7 @@ namespace Octokit.Reactive
Milestone = new ObservableMilestonesClient(client); Milestone = new ObservableMilestonesClient(client);
Comment = new ObservableIssueCommentsClient(client); Comment = new ObservableIssueCommentsClient(client);
Timeline = new ObservableIssueTimelineClient(client); Timeline = new ObservableIssueTimelineClient(client);
LockUnlock = new ObservableLockUnlockClient(client);
} }
/// <summary> /// <summary>
@@ -473,58 +479,6 @@ namespace Octokit.Reactive
return _client.Update(repositoryId, number, issueUpdate).ToObservable(); return _client.Update(repositoryId, number, issueUpdate).ToObservable();
} }
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-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="lockReason">The reason for locking the issue</param>
public IObservable<Unit> Lock(string owner, string name, int number, LockReason? lockReason = null)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
return _client.Lock(owner, name, number, lockReason).ToObservable();
}
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="lockReason">The reason for locking the issue</param>
public IObservable<Unit> Lock(long repositoryId, int number, LockReason? lockReason = null)
{
return _client.Lock(repositoryId, number, lockReason).ToObservable();
}
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-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>
public IObservable<Unit> Unlock(string owner, string name, int number)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
return _client.Unlock(owner, name, number).ToObservable();
}
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
public IObservable<Unit> Unlock(long repositoryId, int number)
{
return _client.Unlock(repositoryId, number).ToObservable();
}
} }
} }

View File

@@ -0,0 +1,75 @@
using System;
using System.Reactive;
using System.Reactive.Threading.Tasks;
namespace Octokit.Reactive
{
/// <summary>
/// Client to manage locking/unlocking a conversation for an Issue or a Pull request
/// </summary>
public class ObservableLockUnlockClient : IObservableLockUnlockClient
{
readonly ILockUnlockClient _client;
public ObservableLockUnlockClient(IGitHubClient client)
{
Ensure.ArgumentNotNull(client, nameof(client));
_client = client.Issue.LockUnlock;
}
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-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="lockReason">The reason for locking the issue</param>
public IObservable<Unit> Lock(string owner, string name, int number, LockReason? lockReason = null)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
return _client.Lock(owner, name, number, lockReason).ToObservable();
}
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="lockReason">The reason for locking the issue</param>
public IObservable<Unit> Lock(long repositoryId, int number, LockReason? lockReason = null)
{
return _client.Lock(repositoryId, number, lockReason).ToObservable();
}
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-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>
public IObservable<Unit> Unlock(string owner, string name, int number)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
return _client.Unlock(owner, name, number).ToObservable();
}
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
public IObservable<Unit> Unlock(long repositoryId, int number)
{
return _client.Unlock(repositoryId, number).ToObservable();
}
}
}

View File

@@ -30,6 +30,11 @@ namespace Octokit.Reactive
/// </summary> /// </summary>
public IObservablePullRequestReviewRequestsClient ReviewRequest { get; private set; } public IObservablePullRequestReviewRequestsClient ReviewRequest { get; private set; }
/// <summary>
/// Client for locking/unlocking a conversation on a pull request
/// </summary>
public IObservableLockUnlockClient LockUnlock { get; private set; }
public ObservablePullRequestsClient(IGitHubClient client) public ObservablePullRequestsClient(IGitHubClient client)
{ {
Ensure.ArgumentNotNull(client, nameof(client)); Ensure.ArgumentNotNull(client, nameof(client));
@@ -39,6 +44,7 @@ namespace Octokit.Reactive
Review = new ObservablePullRequestReviewsClient(client); Review = new ObservablePullRequestReviewsClient(client);
ReviewComment = new ObservablePullRequestReviewCommentsClient(client); ReviewComment = new ObservablePullRequestReviewCommentsClient(client);
ReviewRequest = new ObservablePullRequestReviewRequestsClient(client); ReviewRequest = new ObservablePullRequestReviewRequestsClient(client);
LockUnlock = new ObservableLockUnlockClient(client);
} }
/// <summary> /// <summary>

View File

@@ -241,12 +241,12 @@ public class IssuesClientTests : IDisposable
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
Assert.False(issue.Locked); Assert.False(issue.Locked);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var retrieved = await _issuesClient.Get(_context.RepositoryOwner, _context.RepositoryName, issue.Number); var retrieved = await _issuesClient.Get(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
Assert.NotNull(retrieved); Assert.NotNull(retrieved);
Assert.True(retrieved.Locked); Assert.True(retrieved.Locked);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
retrieved = await _issuesClient.Get(_context.RepositoryOwner, _context.RepositoryName, issue.Number); retrieved = await _issuesClient.Get(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
Assert.NotNull(retrieved); Assert.NotNull(retrieved);
Assert.False(retrieved.Locked); Assert.False(retrieved.Locked);
@@ -259,7 +259,7 @@ public class IssuesClientTests : IDisposable
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
Assert.False(issue.Locked); Assert.False(issue.Locked);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number, LockReason.OffTopic); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number, LockReason.OffTopic);
var retrieved = await _issuesClient.Get(_context.RepositoryOwner, _context.RepositoryName, issue.Number); var retrieved = await _issuesClient.Get(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
Assert.NotNull(retrieved); Assert.NotNull(retrieved);
Assert.True(retrieved.Locked); Assert.True(retrieved.Locked);
@@ -273,12 +273,12 @@ public class IssuesClientTests : IDisposable
var issue = await _issuesClient.Create(_context.Repository.Id, newIssue); var issue = await _issuesClient.Create(_context.Repository.Id, newIssue);
Assert.False(issue.Locked); Assert.False(issue.Locked);
await _issuesClient.Lock(_context.Repository.Id, issue.Number); await _issuesClient.LockUnlock.Lock(_context.Repository.Id, issue.Number);
var retrieved = await _issuesClient.Get(_context.Repository.Id, issue.Number); var retrieved = await _issuesClient.Get(_context.Repository.Id, issue.Number);
Assert.NotNull(retrieved); Assert.NotNull(retrieved);
Assert.True(retrieved.Locked); Assert.True(retrieved.Locked);
await _issuesClient.Unlock(_context.Repository.Id, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.Repository.Id, issue.Number);
retrieved = await _issuesClient.Get(_context.Repository.Id, issue.Number); retrieved = await _issuesClient.Get(_context.Repository.Id, issue.Number);
Assert.NotNull(retrieved); Assert.NotNull(retrieved);
Assert.False(retrieved.Locked); Assert.False(retrieved.Locked);

View File

@@ -63,9 +63,9 @@ public class IssuesEventsClientTests : IDisposable
{ {
var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" }; var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" };
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var options = new ApiOptions var options = new ApiOptions
{ {
@@ -83,9 +83,9 @@ public class IssuesEventsClientTests : IDisposable
{ {
var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" }; var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" };
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var options = new ApiOptions var options = new ApiOptions
{ {
@@ -103,9 +103,9 @@ public class IssuesEventsClientTests : IDisposable
{ {
var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" }; var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" };
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var options = new ApiOptions var options = new ApiOptions
{ {
@@ -124,9 +124,9 @@ public class IssuesEventsClientTests : IDisposable
{ {
var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" }; var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" };
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var options = new ApiOptions var options = new ApiOptions
{ {
@@ -145,9 +145,9 @@ public class IssuesEventsClientTests : IDisposable
{ {
var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" }; var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" };
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var startOptions = new ApiOptions var startOptions = new ApiOptions
{ {
@@ -174,9 +174,9 @@ public class IssuesEventsClientTests : IDisposable
{ {
var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" }; var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" };
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var startOptions = new ApiOptions var startOptions = new ApiOptions
{ {
@@ -259,9 +259,9 @@ public class IssuesEventsClientTests : IDisposable
{ {
var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" }; var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" };
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var options = new ApiOptions var options = new ApiOptions
{ {
@@ -279,9 +279,9 @@ public class IssuesEventsClientTests : IDisposable
{ {
var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" }; var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" };
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var options = new ApiOptions var options = new ApiOptions
{ {
@@ -299,9 +299,9 @@ public class IssuesEventsClientTests : IDisposable
{ {
var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" }; var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" };
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var options = new ApiOptions var options = new ApiOptions
{ {
@@ -320,9 +320,9 @@ public class IssuesEventsClientTests : IDisposable
{ {
var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" }; var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" };
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var options = new ApiOptions var options = new ApiOptions
{ {
@@ -341,9 +341,9 @@ public class IssuesEventsClientTests : IDisposable
{ {
var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" }; var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" };
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var startOptions = new ApiOptions var startOptions = new ApiOptions
{ {
@@ -370,9 +370,9 @@ public class IssuesEventsClientTests : IDisposable
{ {
var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" }; var newIssue = new NewIssue("issue 1") { Body = "A new unassigned issue" };
var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); await _issuesClient.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
var startOptions = new ApiOptions var startOptions = new ApiOptions
{ {

View File

@@ -653,6 +653,25 @@ public class PullRequestsClientTests : IDisposable
Assert.Equal(pullRequest.Body, result.Body); Assert.Equal(pullRequest.Body, result.Body);
} }
[IntegrationTest]
public async Task CanLockAndUnlock()
{
await CreateTheWorld();
var newPullRequest = new NewPullRequest("a pull request to lock", branchName, "main");
var pullRequest = await _fixture.Create(Helper.UserName, _context.RepositoryName, newPullRequest);
await _fixture.LockUnlock.Lock(Helper.UserName, _context.RepositoryName, pullRequest.Number, LockReason.OffTopic);
var retrived = await _fixture.Get(Helper.UserName, _context.RepositoryName, pullRequest.Number);
Assert.Equal(retrived.ActiveLockReason, LockReason.OffTopic);
await _fixture.LockUnlock.Unlock(Helper.UserName, _context.RepositoryName, pullRequest.Number);
var unlocked = await _fixture.Get(Helper.UserName, _context.RepositoryName, pullRequest.Number);
Assert.Null(unlocked.ActiveLockReason);
}
[IntegrationTest] [IntegrationTest]
public async Task CanFindClosedPullRequest() public async Task CanFindClosedPullRequest()
{ {

View File

@@ -118,11 +118,11 @@ public class ObservableIssuesClientTests : IDisposable
var createResult = await _client.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue); var createResult = await _client.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
Assert.False(createResult.Locked); Assert.False(createResult.Locked);
await _client.Lock(_context.RepositoryOwner, _context.RepositoryName, createResult.Number); await _client.LockUnlock.Lock(_context.RepositoryOwner, _context.RepositoryName, createResult.Number);
var lockResult = await _client.Get(_context.RepositoryOwner, _context.RepositoryName, createResult.Number); var lockResult = await _client.Get(_context.RepositoryOwner, _context.RepositoryName, createResult.Number);
Assert.True(lockResult.Locked); Assert.True(lockResult.Locked);
await _client.Unlock(_context.RepositoryOwner, _context.RepositoryName, createResult.Number); await _client.LockUnlock.Unlock(_context.RepositoryOwner, _context.RepositoryName, createResult.Number);
var unlockIssueResult = await _client.Get(_context.RepositoryOwner, _context.RepositoryName, createResult.Number); var unlockIssueResult = await _client.Get(_context.RepositoryOwner, _context.RepositoryName, createResult.Number);
Assert.False(unlockIssueResult.Locked); Assert.False(unlockIssueResult.Locked);
} }

View File

@@ -478,7 +478,7 @@ namespace Octokit.Tests.Clients
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new IssuesClient(connection); var client = new IssuesClient(connection);
client.Lock("fake", "repo", 42); client.LockUnlock.Lock("fake", "repo", 42);
connection.Received().Put<Issue>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/issues/42/lock"), Arg.Any<object>()); connection.Received().Put<Issue>(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/issues/42/lock"), Arg.Any<object>());
} }
@@ -489,7 +489,7 @@ namespace Octokit.Tests.Clients
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new IssuesClient(connection); var client = new IssuesClient(connection);
client.Lock(1, 42); client.LockUnlock.Lock(1, 42);
connection.Received().Put<Issue>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/issues/42/lock"), Arg.Any<object>()); connection.Received().Put<Issue>(Arg.Is<Uri>(u => u.ToString() == "repositories/1/issues/42/lock"), Arg.Any<object>());
} }
@@ -500,11 +500,11 @@ namespace Octokit.Tests.Clients
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new IssuesClient(connection); var client = new IssuesClient(connection);
await Assert.ThrowsAsync<ArgumentNullException>(() => client.Lock(null, "name", 1)); await Assert.ThrowsAsync<ArgumentNullException>(() => client.LockUnlock.Lock(null, "name", 1));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.Lock("owner", null, 1)); await Assert.ThrowsAsync<ArgumentNullException>(() => client.LockUnlock.Lock("owner", null, 1));
await Assert.ThrowsAsync<ArgumentException>(() => client.Lock("", "name", 1)); await Assert.ThrowsAsync<ArgumentException>(() => client.LockUnlock.Lock("", "name", 1));
await Assert.ThrowsAsync<ArgumentException>(() => client.Lock("owner", "", 1)); await Assert.ThrowsAsync<ArgumentException>(() => client.LockUnlock.Lock("owner", "", 1));
} }
} }
@@ -516,7 +516,7 @@ namespace Octokit.Tests.Clients
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new IssuesClient(connection); var client = new IssuesClient(connection);
client.Unlock("fake", "repo", 42); client.LockUnlock.Unlock("fake", "repo", 42);
connection.Received().Delete(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/issues/42/lock")); connection.Received().Delete(Arg.Is<Uri>(u => u.ToString() == "repos/fake/repo/issues/42/lock"));
} }
@@ -527,7 +527,7 @@ namespace Octokit.Tests.Clients
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new IssuesClient(connection); var client = new IssuesClient(connection);
client.Unlock(1, 42); client.LockUnlock.Unlock(1, 42);
connection.Received().Delete(Arg.Is<Uri>(u => u.ToString() == "repositories/1/issues/42/lock")); connection.Received().Delete(Arg.Is<Uri>(u => u.ToString() == "repositories/1/issues/42/lock"));
} }
@@ -538,11 +538,11 @@ namespace Octokit.Tests.Clients
var connection = Substitute.For<IApiConnection>(); var connection = Substitute.For<IApiConnection>();
var client = new IssuesClient(connection); var client = new IssuesClient(connection);
await Assert.ThrowsAsync<ArgumentNullException>(() => client.Unlock(null, "name", 1)); await Assert.ThrowsAsync<ArgumentNullException>(() => client.LockUnlock.Unlock(null, "name", 1));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.Unlock("owner", null, 1)); await Assert.ThrowsAsync<ArgumentNullException>(() => client.LockUnlock.Unlock("owner", null, 1));
await Assert.ThrowsAsync<ArgumentException>(() => client.Unlock("", "name", 1)); await Assert.ThrowsAsync<ArgumentException>(() => client.LockUnlock.Unlock("", "name", 1));
await Assert.ThrowsAsync<ArgumentException>(() => client.Unlock("owner", "", 1)); await Assert.ThrowsAsync<ArgumentException>(() => client.LockUnlock.Unlock("owner", "", 1));
} }
} }

View File

@@ -645,9 +645,9 @@ public class ObservableIssuesClientTests
var gitHubClient = Substitute.For<IGitHubClient>(); var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableIssuesClient(gitHubClient); var client = new ObservableIssuesClient(gitHubClient);
client.Lock("fake", "repo", 42); client.LockUnlock.Lock("fake", "repo", 42);
gitHubClient.Issue.Received().Lock("fake", "repo", 42); gitHubClient.Issue.Received().LockUnlock.Lock("fake", "repo", 42);
} }
[Fact] [Fact]
@@ -656,9 +656,9 @@ public class ObservableIssuesClientTests
var gitHubClient = Substitute.For<IGitHubClient>(); var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableIssuesClient(gitHubClient); var client = new ObservableIssuesClient(gitHubClient);
client.Lock(1, 42); client.LockUnlock.Lock(1, 42);
gitHubClient.Issue.Received().Lock(1, 42); gitHubClient.Issue.Received().LockUnlock.Lock(1, 42);
} }
[Fact] [Fact]
@@ -667,11 +667,11 @@ public class ObservableIssuesClientTests
var gitHubClient = Substitute.For<IGitHubClient>(); var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableIssuesClient(gitHubClient); var client = new ObservableIssuesClient(gitHubClient);
Assert.Throws<ArgumentNullException>(() => client.Lock(null, "name", 42)); Assert.Throws<ArgumentNullException>(() => client.LockUnlock.Lock(null, "name", 42));
Assert.Throws<ArgumentNullException>(() => client.Lock("owner", null, 42)); Assert.Throws<ArgumentNullException>(() => client.LockUnlock.Lock("owner", null, 42));
Assert.Throws<ArgumentException>(() => client.Lock("", "name", 42)); Assert.Throws<ArgumentException>(() => client.LockUnlock.Lock("", "name", 42));
Assert.Throws<ArgumentException>(() => client.Lock("owner", "", 42)); Assert.Throws<ArgumentException>(() => client.LockUnlock.Lock("owner", "", 42));
} }
} }
@@ -683,9 +683,9 @@ public class ObservableIssuesClientTests
var gitHubClient = Substitute.For<IGitHubClient>(); var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableIssuesClient(gitHubClient); var client = new ObservableIssuesClient(gitHubClient);
client.Unlock("fake", "repo", 42); client.LockUnlock.Unlock("fake", "repo", 42);
gitHubClient.Issue.Received().Unlock("fake", "repo", 42); gitHubClient.Issue.Received().LockUnlock.Unlock("fake", "repo", 42);
} }
[Fact] [Fact]
@@ -694,9 +694,9 @@ public class ObservableIssuesClientTests
var gitHubClient = Substitute.For<IGitHubClient>(); var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableIssuesClient(gitHubClient); var client = new ObservableIssuesClient(gitHubClient);
client.Unlock(1, 42); client.LockUnlock.Unlock(1, 42);
gitHubClient.Issue.Received().Unlock(1, 42); gitHubClient.Issue.Received().LockUnlock.Unlock(1, 42);
} }
[Fact] [Fact]
@@ -705,11 +705,11 @@ public class ObservableIssuesClientTests
var gitHubClient = Substitute.For<IGitHubClient>(); var gitHubClient = Substitute.For<IGitHubClient>();
var client = new ObservableIssuesClient(gitHubClient); var client = new ObservableIssuesClient(gitHubClient);
Assert.Throws<ArgumentNullException>(() => client.Unlock(null, "name", 42)); Assert.Throws<ArgumentNullException>(() => client.LockUnlock.Unlock(null, "name", 42));
Assert.Throws<ArgumentNullException>(() => client.Unlock("owner", null, 42)); Assert.Throws<ArgumentNullException>(() => client.LockUnlock.Unlock("owner", null, 42));
Assert.Throws<ArgumentException>(() => client.Unlock("", "name", 42)); Assert.Throws<ArgumentException>(() => client.LockUnlock.Unlock("", "name", 42));
Assert.Throws<ArgumentException>(() => client.Unlock("owner", "", 42)); Assert.Throws<ArgumentException>(() => client.LockUnlock.Unlock("owner", "", 42));
} }
} }

View File

@@ -41,6 +41,8 @@ namespace Octokit
IIssueTimelineClient Timeline { get; } IIssueTimelineClient Timeline { get; }
ILockUnlockClient LockUnlock { get; }
/// <summary> /// <summary>
/// Gets a single Issue by number. /// Gets a single Issue by number.
/// </summary> /// </summary>
@@ -314,40 +316,5 @@ namespace Octokit
/// </param> /// </param>
Task<Issue> Update(long repositoryId, int number, IssueUpdate issueUpdate); Task<Issue> Update(long repositoryId, int number, IssueUpdate issueUpdate);
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-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="lockReason">The reason for locking the issue</param>
Task Lock(string owner, string name, int number, LockReason? lockReason = null);
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="lockReason">The reason for locking the issue</param>
Task Lock(long repositoryId, int number, LockReason? lockReason = null);
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-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>
Task Unlock(string owner, string name, int number);
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
Task Unlock(long repositoryId, int number);
} }
} }

View File

@@ -0,0 +1,47 @@
using System.Threading.Tasks;
namespace Octokit
{
/// <summary>
/// Client to manage locking/unlocking a conversation for an Issue or a Pull request
/// </summary>
public interface ILockUnlockClient
{
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue or pull request's conversation.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-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="lockReason">The reason for locking the issue</param>
Task Lock(string owner, string name, int number, LockReason? lockReason = null);
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue or pull request's conversation.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="lockReason">The reason for locking the issue</param>
Task Lock(long repositoryId, int number, LockReason? lockReason = null);
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue or pull request's conversation.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-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>
Task Unlock(string owner, string name, int number);
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue or pull request's conversation.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
Task Unlock(long repositoryId, int number);
}
}

View File

@@ -28,6 +28,11 @@ namespace Octokit
/// </summary> /// </summary>
IPullRequestReviewRequestsClient ReviewRequest { get; } IPullRequestReviewRequestsClient ReviewRequest { get; }
/// <summary>
/// Client for locking/unlocking a coversation on a pull request
/// </summary>
ILockUnlockClient LockUnlock { get; }
/// <summary> /// <summary>
/// Get a pull request by number. /// Get a pull request by number.
/// </summary> /// </summary>

View File

@@ -23,6 +23,7 @@ namespace Octokit
Milestone = new MilestonesClient(apiConnection); Milestone = new MilestonesClient(apiConnection);
Comment = new IssueCommentsClient(apiConnection); Comment = new IssueCommentsClient(apiConnection);
Timeline = new IssueTimelineClient(apiConnection); Timeline = new IssueTimelineClient(apiConnection);
LockUnlock = new LockUnlockClient(apiConnection);
} }
/// <summary> /// <summary>
@@ -57,6 +58,11 @@ namespace Octokit
/// </summary> /// </summary>
public IIssueTimelineClient Timeline { get; private set; } public IIssueTimelineClient Timeline { get; private set; }
/// <summary>
/// Client for locking and unlocking a conversation on a Issue or Pull request
/// </summary>
public ILockUnlockClient LockUnlock { get; private set; }
/// <summary> /// <summary>
/// Gets a single Issue by number. /// Gets a single Issue by number.
/// </summary> /// </summary>
@@ -491,64 +497,6 @@ namespace Octokit
Ensure.ArgumentNotNull(issueUpdate, nameof(issueUpdate)); Ensure.ArgumentNotNull(issueUpdate, nameof(issueUpdate));
return ApiConnection.Patch<Issue>(ApiUrls.Issue(repositoryId, number), issueUpdate); return ApiConnection.Patch<Issue>(ApiUrls.Issue(repositoryId, number), issueUpdate);
} }
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-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="lockReason">The reason for locking the issue</param>
[ManualRoute("PUT", "/repos/{owner}/{repo}/issues/{issue_number}/lock")]
public Task Lock(string owner, string name, int number, LockReason? lockReason = null)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
return ApiConnection.Put<Issue>(ApiUrls.IssueLock(owner, name, number), lockReason.HasValue ? new { LockReason = lockReason } : new object());
}
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="lockReason">The reason for locking the issue</param>
[ManualRoute("PUT", "/repositories/{id}/issues/{number}/lock")]
public Task Lock(long repositoryId, int number, LockReason? lockReason = null)
{
return ApiConnection.Put<Issue>(ApiUrls.IssueLock(repositoryId, number), lockReason.HasValue ? new { LockReaons = lockReason } : new object());
}
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-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>
[ManualRoute("DELETE", "/repos/{owner}/{repo}/issues/{issue_number}/lock")]
public Task Unlock(string owner, string name, int number)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
return ApiConnection.Delete(ApiUrls.IssueLock(owner, name, number));
}
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
[ManualRoute("DELETE", "/repositories/{id}/issues/{number}/lock")]
public Task Unlock(long repositoryId, int number)
{
return ApiConnection.Delete(ApiUrls.IssueLock(repositoryId, number));
}
} }
} }

View File

@@ -0,0 +1,76 @@
using System.Threading.Tasks;
namespace Octokit
{
/// <summary>
/// Client to manage locking/unlocking a conversation for an Issue or a Pull request
/// </summary>
public class LockUnlockClient : ApiClient, ILockUnlockClient
{
/// <summary>
/// Instantiates a new GitHub Issue Lock API client.
/// </summary>
/// <param name="apiConnection">An API connection</param>
public LockUnlockClient(IApiConnection apiConnection) : base(apiConnection)
{
}
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue or pull request's conversation.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-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="lockReason">The reason for locking the issue</param>
[ManualRoute("PUT", "/repos/{owner}/{repo}/issues/{issue_number}/lock")]
public Task Lock(string owner, string name, int number, LockReason? lockReason = null)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
return ApiConnection.Put<Issue>(ApiUrls.IssueLock(owner, name, number), lockReason.HasValue ? new { LockReason = lockReason } : new object());
}
/// <summary>
/// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue or pull request's conversation.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#lock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
/// <param name="lockReason">The reason for locking the issue</param>
[ManualRoute("PUT", "/repositories/{id}/issues/{number}/lock")]
public Task Lock(long repositoryId, int number, LockReason? lockReason = null)
{
return ApiConnection.Put<Issue>(ApiUrls.IssueLock(repositoryId, number), lockReason.HasValue ? new { LockReaons = lockReason } : new object());
}
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue or pull request's conversation.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-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>
[ManualRoute("DELETE", "/repos/{owner}/{repo}/issues/{issue_number}/lock")]
public Task Unlock(string owner, string name, int number)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
return ApiConnection.Delete(ApiUrls.IssueLock(owner, name, number));
}
/// <summary>
/// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue or pull request's conversation.
/// </summary>
/// <remarks>https://developer.github.com/v3/issues/#unlock-an-issue</remarks>
/// <param name="repositoryId">The Id of the repository</param>
/// <param name="number">The issue number</param>
[ManualRoute("DELETE", "/repositories/{id}/issues/{number}/lock")]
public Task Unlock(long repositoryId, int number)
{
return ApiConnection.Delete(ApiUrls.IssueLock(repositoryId, number));
}
}
}

View File

@@ -18,6 +18,7 @@ namespace Octokit
Review = new PullRequestReviewsClient(apiConnection); Review = new PullRequestReviewsClient(apiConnection);
ReviewComment = new PullRequestReviewCommentsClient(apiConnection); ReviewComment = new PullRequestReviewCommentsClient(apiConnection);
ReviewRequest = new PullRequestReviewRequestsClient(apiConnection); ReviewRequest = new PullRequestReviewRequestsClient(apiConnection);
LockUnlock = new LockUnlockClient(apiConnection);
} }
/// <summary> /// <summary>
@@ -35,6 +36,11 @@ namespace Octokit
/// </summary> /// </summary>
public IPullRequestReviewRequestsClient ReviewRequest { get; set; } public IPullRequestReviewRequestsClient ReviewRequest { get; set; }
/// <summary>
/// Client for locking/unlocking a coversation on a pull request
/// </summary>
public ILockUnlockClient LockUnlock { get; set; }
/// <summary> /// <summary>
/// Get a pull request by number. /// Get a pull request by number.
/// </summary> /// </summary>

View File

@@ -16,7 +16,7 @@ namespace Octokit
Number = number; Number = number;
} }
public PullRequest(long id, string nodeId, string url, string htmlUrl, string diffUrl, string patchUrl, string issueUrl, string statusesUrl, int number, ItemState state, string title, string body, DateTimeOffset createdAt, DateTimeOffset updatedAt, DateTimeOffset? closedAt, DateTimeOffset? mergedAt, GitReference head, GitReference @base, User user, User assignee, IReadOnlyList<User> assignees, bool draft, bool? mergeable, MergeableState? mergeableState, User mergedBy, string mergeCommitSha, int comments, int commits, int additions, int deletions, int changedFiles, Milestone milestone, bool locked, bool? maintainerCanModify, IReadOnlyList<User> requestedReviewers, IReadOnlyList<Team> requestedTeams, IReadOnlyList<Label> labels) public PullRequest(long id, string nodeId, string url, string htmlUrl, string diffUrl, string patchUrl, string issueUrl, string statusesUrl, int number, ItemState state, string title, string body, DateTimeOffset createdAt, DateTimeOffset updatedAt, DateTimeOffset? closedAt, DateTimeOffset? mergedAt, GitReference head, GitReference @base, User user, User assignee, IReadOnlyList<User> assignees, bool draft, bool? mergeable, MergeableState? mergeableState, User mergedBy, string mergeCommitSha, int comments, int commits, int additions, int deletions, int changedFiles, Milestone milestone, bool locked, bool? maintainerCanModify, IReadOnlyList<User> requestedReviewers, IReadOnlyList<Team> requestedTeams, IReadOnlyList<Label> labels, LockReason? activeLockReason)
{ {
Id = id; Id = id;
NodeId = nodeId; NodeId = nodeId;
@@ -55,6 +55,7 @@ namespace Octokit
RequestedReviewers = requestedReviewers; RequestedReviewers = requestedReviewers;
RequestedTeams = requestedTeams; RequestedTeams = requestedTeams;
Labels = labels; Labels = labels;
ActiveLockReason = activeLockReason;
} }
/// <summary> /// <summary>
@@ -251,6 +252,11 @@ namespace Octokit
public IReadOnlyList<Label> Labels { get; protected set; } public IReadOnlyList<Label> Labels { get; protected set; }
/// <summary>
/// Reason that the conversation was locked
/// </summary>
public StringEnum<LockReason>? ActiveLockReason { get; protected set; }
internal string DebuggerDisplay internal string DebuggerDisplay
{ {
get { return string.Format(CultureInfo.InvariantCulture, "Number: {0} State: {1}", Number, State); } get { return string.Format(CultureInfo.InvariantCulture, "Number: {0} State: {1}", Number, State); }

View File

@@ -120,3 +120,23 @@ Label changes probably requires some explanation:
If you're trying to populate the `Labels` collection by hand, you might hit If you're trying to populate the `Labels` collection by hand, you might hit
some exceptional behaviour due to these rules. some exceptional behaviour due to these rules.
### Lock / Unlock
The lock and unlock methods are available on the ILockUnlockClient on IIssuesClient.
Heres a sample code for locking an issue:
```csharp
var issue = await client.Issue.Get("octokit", "octokit.net", 405);
await client.LockUnlock.Lock("octokit", "octokit.net", 405, LockReason.OffTopic);
```
The active lock reason can be accessed via the LockReason property on Issues class.
The code below demonstrates how to unlock an issue:
```csharp
var issue = await client.Issue.Get("octokit", "octokit.net", 405);
await client.LockUnlock.Unlock("octokit", "octokit.net", 405);
```