diff --git a/Octokit.Reactive/Clients/IObservableIssuesClient.cs b/Octokit.Reactive/Clients/IObservableIssuesClient.cs
index 008d9955b0..cae13e02a1 100644
--- a/Octokit.Reactive/Clients/IObservableIssuesClient.cs
+++ b/Octokit.Reactive/Clients/IObservableIssuesClient.cs
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics.CodeAnalysis;
+using System.Reactive;
namespace Octokit.Reactive
{
@@ -156,5 +157,25 @@ public interface IObservableIssuesClient
///
///
IObservable Update(string owner, string name, int number, IssueUpdate issueUpdate);
+
+ ///
+ /// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
+ ///
+ /// https://developer.github.com/v3/issues/#lock-an-issue
+ /// The owner of the repository
+ /// The name of the repository
+ /// The issue number
+ ///
+ IObservable LockIssue(string owner, string name, int number);
+
+ ///
+ /// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
+ ///
+ /// https://developer.github.com/v3/issues/#unlock-an-issue
+ /// The owner of the repository
+ /// The name of the repository
+ /// The issue number
+ ///
+ IObservable UnlockIssue(string owner, string name, int number);
}
-}
+}
\ No newline at end of file
diff --git a/Octokit.Reactive/Clients/ObservableIssuesClient.cs b/Octokit.Reactive/Clients/ObservableIssuesClient.cs
index 4571696334..47d2b9f07b 100644
--- a/Octokit.Reactive/Clients/ObservableIssuesClient.cs
+++ b/Octokit.Reactive/Clients/ObservableIssuesClient.cs
@@ -1,6 +1,7 @@
using System;
using System.Reactive.Threading.Tasks;
using Octokit.Reactive.Internal;
+using System.Reactive;
namespace Octokit.Reactive
{
@@ -222,5 +223,37 @@ public IObservable Update(string owner, string name, int number, IssueUpd
return _client.Update(owner, name, number, issueUpdate).ToObservable();
}
+
+ ///
+ /// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
+ ///
+ /// https://developer.github.com/v3/issues/#lock-an-issue
+ /// The owner of the repository
+ /// The name of the repository
+ /// The issue number
+ ///
+ public IObservable LockIssue(string owner, string name, int number)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
+ Ensure.ArgumentNotNullOrEmptyString(name, "name");
+
+ return _client.LockIssue(owner, name, number).ToObservable();
+ }
+
+ ///
+ /// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
+ ///
+ /// https://developer.github.com/v3/issues/#unlock-an-issue
+ /// The owner of the repository
+ /// The name of the repository
+ /// The issue number
+ ///
+ public IObservable UnlockIssue(string owner, string name, int number)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
+ Ensure.ArgumentNotNullOrEmptyString(name, "name");
+
+ return _client.UnlockIssue(owner, name, number).ToObservable();
+ }
}
}
diff --git a/Octokit.Tests.Integration/Clients/IssuesClientTests.cs b/Octokit.Tests.Integration/Clients/IssuesClientTests.cs
index 73284093a5..fec271d0bf 100644
--- a/Octokit.Tests.Integration/Clients/IssuesClientTests.cs
+++ b/Octokit.Tests.Integration/Clients/IssuesClientTests.cs
@@ -62,6 +62,26 @@ public async Task CanCreateRetrieveAndCloseIssue()
}
[IntegrationTest]
+ public async Task CanLockAndUnlockIssue()
+ {
+ var newIssue = new NewIssue("a test issue") { Body = "A new unassigned issue" };
+ var issue = await _issuesClient.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
+ var retrieved = await _issuesClient.Get(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
+
+ Assert.Equal(false, issue.Locked);
+
+ await _issuesClient.LockIssue(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
+ retrieved = await _issuesClient.Get(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
+ Assert.NotNull(retrieved);
+ Assert.Equal(true, issue.Locked);
+
+ await _issuesClient.UnlockIssue(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
+ retrieved = await _issuesClient.Get(_context.RepositoryOwner, _context.RepositoryName, issue.Number);
+ Assert.NotNull(retrieved);
+ Assert.Equal(false, issue.Locked);
+ }
+
+ [IntegrationTest]
public async Task CanListOpenIssuesWithDefaultSort()
{
var newIssue1 = new NewIssue("A test issue1") { Body = "A new unassigned issue" };
diff --git a/Octokit.Tests.Integration/Reactive/ObservableIssuesClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableIssuesClientTests.cs
index 5eb94af756..1b40a7ac92 100644
--- a/Octokit.Tests.Integration/Reactive/ObservableIssuesClientTests.cs
+++ b/Octokit.Tests.Integration/Reactive/ObservableIssuesClientTests.cs
@@ -72,6 +72,23 @@ public async Task CanCreateAndUpdateIssues()
Assert.Equal("Modified integration test issue", updateResult.Title);
}
+ [IntegrationTest]
+ public async Task CanLockAndUnlockIssues()
+ {
+ var newIssue = new NewIssue("Integration Test Issue");
+
+ var createResult = await _client.Create(_context.RepositoryOwner, _context.RepositoryName, newIssue);
+ Assert.Equal(false, createResult.Locked);
+
+ await _client.LockIssue(_context.RepositoryOwner, _context.RepositoryName, createResult.Number);
+ var lockResult = await _client.Get(_context.RepositoryOwner, _context.RepositoryName, createResult.Number);
+ Assert.Equal(true, lockResult.Locked);
+
+ await _client.UnlockIssue(_context.RepositoryOwner, _context.RepositoryName, createResult.Number);
+ var unlockIssueResult = await _client.Get(_context.RepositoryOwner, _context.RepositoryName, createResult.Number);
+ Assert.Equal(false, unlockIssueResult.Locked);
+ }
+
public void Dispose()
{
_context.Dispose();
diff --git a/Octokit.Tests/Clients/IssuesClientTests.cs b/Octokit.Tests/Clients/IssuesClientTests.cs
index 2f3b759b19..f4086d6833 100644
--- a/Octokit.Tests/Clients/IssuesClientTests.cs
+++ b/Octokit.Tests/Clients/IssuesClientTests.cs
@@ -185,6 +185,58 @@ public async Task EnsuresArgumentsNotNull()
}
}
+ public class TheLockIssueMethod
+ {
+ [Fact]
+ public void PostsToCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new IssuesClient(connection);
+
+ client.LockIssue("fake", "repo", 42);
+
+ connection.Received().Put(Arg.Is(u => u.ToString() == "repos/fake/repo/issues/42/lock"));
+ }
+
+ [Fact]
+ public async Task EnsuresArgumentsNotNull()
+ {
+ var connection = Substitute.For();
+ var client = new IssuesClient(connection);
+
+ await Assert.ThrowsAsync(() => client.LockIssue(null, "name", 1));
+ await Assert.ThrowsAsync(() => client.LockIssue("", "name", 1));
+ await Assert.ThrowsAsync(() => client.LockIssue("owner", null, 1));
+ await Assert.ThrowsAsync(() => client.LockIssue("owner", "", 1));
+ }
+ }
+
+ public class TheUnlockIssueMethod
+ {
+ [Fact]
+ public void PostsToCorrectUrl()
+ {
+ var connection = Substitute.For();
+ var client = new IssuesClient(connection);
+
+ client.UnlockIssue("fake", "repo", 42);
+
+ connection.Received().Delete(Arg.Is(u => u.ToString() == "repos/fake/repo/issues/42/lock"));
+ }
+
+ [Fact]
+ public async Task EnsuresArgumentsNotNull()
+ {
+ var connection = Substitute.For();
+ var client = new IssuesClient(connection);
+
+ await Assert.ThrowsAsync(() => client.UnlockIssue(null, "name", 1));
+ await Assert.ThrowsAsync(() => client.UnlockIssue("", "name", 1));
+ await Assert.ThrowsAsync(() => client.UnlockIssue("owner", null, 1));
+ await Assert.ThrowsAsync(() => client.UnlockIssue("owner", "", 1));
+ }
+ }
+
public class TheCtor
{
[Fact]
diff --git a/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs b/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs
index aa23f958fd..61afa771cd 100644
--- a/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs
+++ b/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs
@@ -329,11 +329,61 @@ public void EnsuresArgumentsNotNull()
var gitHubClient = Substitute.For();
var client = new ObservableIssuesClient(gitHubClient);
- Assert.Throws(() => client.Create(null, "name", new NewIssue("title")));
- Assert.Throws(() => client.Create("", "name", new NewIssue("x")));
- Assert.Throws(() => client.Create("owner", null, new NewIssue("x")));
- Assert.Throws(() => client.Create("owner", "", new NewIssue("x")));
- Assert.Throws(() => client.Create("owner", "name", null));
+ Assert.Throws(() => client.Update(null, "name", 42, new IssueUpdate()));
+ Assert.Throws(() => client.Update("", "name", 42, new IssueUpdate()));
+ Assert.Throws(() => client.Update("owner", null, 42, new IssueUpdate()));
+ Assert.Throws(() => client.Update("owner", "", 42, new IssueUpdate()));
+ Assert.Throws(() => client.Update("owner", "name", 42, null));
+ }
+ }
+
+ public class TheLockIssueMethod
+ {
+ [Fact]
+ public void LockIssue()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableIssuesClient(gitHubClient);
+
+ client.LockIssue("fake", "repo", 42);
+ gitHubClient.Issue.Received().LockIssue("fake", "repo", 42);
+ }
+
+ [Fact]
+ public void EnsuresArgumentsNotNull()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableIssuesClient(gitHubClient);
+
+ Assert.Throws(() => client.LockIssue(null, "name", 42));
+ Assert.Throws(() => client.LockIssue("", "name", 42));
+ Assert.Throws(() => client.LockIssue("owner", null, 42));
+ Assert.Throws(() => client.LockIssue("owner", "", 42));
+ }
+ }
+
+ public class TheUnlockIssueMethod
+ {
+ [Fact]
+ public void UnlockIssue()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableIssuesClient(gitHubClient);
+
+ client.UnlockIssue("fake", "repo", 42);
+ gitHubClient.Issue.Received().UnlockIssue("fake", "repo", 42);
+ }
+
+ [Fact]
+ public void EnsuresArgumentsNotNull()
+ {
+ var gitHubClient = Substitute.For();
+ var client = new ObservableIssuesClient(gitHubClient);
+
+ Assert.Throws(() => client.UnlockIssue(null, "name", 42));
+ Assert.Throws(() => client.UnlockIssue("", "name", 42));
+ Assert.Throws(() => client.UnlockIssue("owner", null, 42));
+ Assert.Throws(() => client.UnlockIssue("owner", "", 42));
}
}
diff --git a/Octokit/Clients/IIssuesClient.cs b/Octokit/Clients/IIssuesClient.cs
index bc0e362cb9..f6f61dea4a 100644
--- a/Octokit/Clients/IIssuesClient.cs
+++ b/Octokit/Clients/IIssuesClient.cs
@@ -152,10 +152,10 @@ public interface IIssuesClient
Task Create(string owner, string name, NewIssue newIssue);
///
- /// Creates an issue for the specified repository. Any user with pull access to a repository can create an
+ /// Updates an issue for the specified repository. Any user with pull access to a repository can update an
/// issue.
///
- /// http://developer.github.com/v3/issues/#create-an-issue
+ /// http://developer.github.com/v3/issues/#edit-an-issue
/// The owner of the repository
/// The name of the repository
/// The issue number
@@ -163,5 +163,25 @@ public interface IIssuesClient
///
///
Task Update(string owner, string name, int number, IssueUpdate issueUpdate);
+
+ ///
+ /// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
+ ///
+ /// https://developer.github.com/v3/issues/#lock-an-issue
+ /// The owner of the repository
+ /// The name of the repository
+ /// The issue number
+ ///
+ Task LockIssue(string owner, string name, int number);
+
+ ///
+ /// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
+ ///
+ /// https://developer.github.com/v3/issues/#unlock-an-issue
+ /// The owner of the repository
+ /// The name of the repository
+ /// The issue number
+ ///
+ Task UnlockIssue(string owner, string name, int number);
}
}
diff --git a/Octokit/Clients/IssuesClient.cs b/Octokit/Clients/IssuesClient.cs
index 8b924245bb..be4a9641b6 100644
--- a/Octokit/Clients/IssuesClient.cs
+++ b/Octokit/Clients/IssuesClient.cs
@@ -225,5 +225,37 @@ public Task Update(string owner, string name, int number, IssueUpdate iss
return ApiConnection.Patch(ApiUrls.Issue(owner, name, number), issueUpdate);
}
+
+ ///
+ /// Locks an issue for the specified repository. Issue owners and users with push access can lock an issue.
+ ///
+ /// https://developer.github.com/v3/issues/#lock-an-issue
+ /// The owner of the repository
+ /// The name of the repository
+ /// The issue number
+ ///
+ public Task LockIssue(string owner, string name, int number)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
+ Ensure.ArgumentNotNullOrEmptyString(name, "name");
+
+ return ApiConnection.Put(ApiUrls.IssueLock(owner, name, number));
+ }
+
+ ///
+ /// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue.
+ ///
+ /// https://developer.github.com/v3/issues/#unlock-an-issue
+ /// The owner of the repository
+ /// The name of the repository
+ /// The issue number
+ ///
+ public Task UnlockIssue(string owner, string name, int number)
+ {
+ Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
+ Ensure.ArgumentNotNullOrEmptyString(name, "name");
+
+ return ApiConnection.Delete(ApiUrls.IssueLock(owner, name, number));
+ }
}
}
diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs
index bb34ce4624..73e99aa3bc 100644
--- a/Octokit/Helpers/ApiUrls.cs
+++ b/Octokit/Helpers/ApiUrls.cs
@@ -294,6 +294,18 @@ public static Uri Issue(string owner, string name, int number)
return "repos/{0}/{1}/issues/{2}".FormatUri(owner, name, number);
}
+ ///
+ /// Returns the for the specified issue to be locked/unlocked.
+ ///
+ /// The owner of the repository
+ /// The name of the repository
+ /// The issue number
+ ///
+ public static Uri IssueLock(string owner, string name, int number)
+ {
+ return "repos/{0}/{1}/issues/{2}/lock".FormatUri(owner, name, number);
+ }
+
///
/// Returns the for the comments for all issues in a specific repo.
///