From 171b3c520a35af7d3fd80c48718623dafb7c474c Mon Sep 17 00:00:00 2001 From: Prayank Mathur Date: Fri, 25 Mar 2016 11:26:37 +0530 Subject: [PATCH 1/7] Implement Lock/Unlock Issue --- .../Clients/IObservableIssuesClient.cs | 23 ++++++- .../Clients/ObservableIssuesClient.cs | 33 ++++++++++ .../Clients/IssuesClientTests.cs | 20 +++++++ .../Reactive/ObservableIssuesClientTests.cs | 17 ++++++ Octokit.Tests/Clients/IssuesClientTests.cs | 52 ++++++++++++++++ .../Reactive/ObservableIssuesClientTests.cs | 60 +++++++++++++++++-- Octokit/Clients/IIssuesClient.cs | 24 +++++++- Octokit/Clients/IssuesClient.cs | 32 ++++++++++ Octokit/Helpers/ApiUrls.cs | 12 ++++ 9 files changed, 265 insertions(+), 8 deletions(-) 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. /// From 2c167bfb706bfc93b771dc8be41ff7b43f683095 Mon Sep 17 00:00:00 2001 From: Prayank Mathur Date: Fri, 25 Mar 2016 12:01:18 +0530 Subject: [PATCH 2/7] Fixes --- Octokit.Tests/Reactive/ObservableIssuesClientTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs b/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs index 61afa771cd..c59bb2e910 100644 --- a/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs @@ -329,11 +329,11 @@ public void EnsuresArgumentsNotNull() var gitHubClient = Substitute.For(); var client = new ObservableIssuesClient(gitHubClient); - 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)); + 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)); } } From 8ff574ab1ce04c59d698f15a2ffba8d80df50265 Mon Sep 17 00:00:00 2001 From: Prayank Mathur Date: Tue, 29 Mar 2016 16:19:47 +0530 Subject: [PATCH 3/7] Changes in Accept headers as well as names of the functions --- .../Clients/IObservableIssuesClient.cs | 4 +-- .../Clients/ObservableIssuesClient.cs | 8 +++--- .../Clients/IssuesClientTests.cs | 25 +++++++++---------- .../Reactive/ObservableIssuesClientTests.cs | 10 ++++---- Octokit/Clients/IIssuesClient.cs | 4 +-- Octokit/Clients/IssuesClient.cs | 8 +++--- Octokit/Helpers/AcceptHeaders.cs | 2 ++ 7 files changed, 31 insertions(+), 30 deletions(-) diff --git a/Octokit.Reactive/Clients/IObservableIssuesClient.cs b/Octokit.Reactive/Clients/IObservableIssuesClient.cs index cae13e02a1..86bbe89de8 100644 --- a/Octokit.Reactive/Clients/IObservableIssuesClient.cs +++ b/Octokit.Reactive/Clients/IObservableIssuesClient.cs @@ -166,7 +166,7 @@ public interface IObservableIssuesClient /// The name of the repository /// The issue number /// - IObservable LockIssue(string owner, string name, int number); + IObservable Lock(string owner, string name, int number); /// /// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue. @@ -176,6 +176,6 @@ public interface IObservableIssuesClient /// The name of the repository /// The issue number /// - IObservable UnlockIssue(string owner, string name, int number); + IObservable Unlock(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 47d2b9f07b..f00095d346 100644 --- a/Octokit.Reactive/Clients/ObservableIssuesClient.cs +++ b/Octokit.Reactive/Clients/ObservableIssuesClient.cs @@ -232,12 +232,12 @@ public IObservable Update(string owner, string name, int number, IssueUpd /// The name of the repository /// The issue number /// - public IObservable LockIssue(string owner, string name, int number) + public IObservable Lock(string owner, string name, int number) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(name, "name"); - return _client.LockIssue(owner, name, number).ToObservable(); + return _client.Lock(owner, name, number).ToObservable(); } /// @@ -248,12 +248,12 @@ public IObservable LockIssue(string owner, string name, int number) /// The name of the repository /// The issue number /// - public IObservable UnlockIssue(string owner, string name, int number) + public IObservable Unlock(string owner, string name, int number) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(name, "name"); - return _client.UnlockIssue(owner, name, number).ToObservable(); + return _client.Unlock(owner, name, number).ToObservable(); } } } diff --git a/Octokit.Tests.Integration/Clients/IssuesClientTests.cs b/Octokit.Tests.Integration/Clients/IssuesClientTests.cs index fec271d0bf..809da6bf9b 100644 --- a/Octokit.Tests.Integration/Clients/IssuesClientTests.cs +++ b/Octokit.Tests.Integration/Clients/IssuesClientTests.cs @@ -64,21 +64,20 @@ 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); + 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.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.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); + retrieved = await _issuesClient.Get(_context.RepositoryOwner, _context.RepositoryName, issue.Number); + Assert.NotNull(retrieved); + Assert.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); + await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); + retrieved = await _issuesClient.Get(_context.RepositoryOwner, _context.RepositoryName, issue.Number); + Assert.NotNull(retrieved); + Assert.False(issue.Locked); } [IntegrationTest] diff --git a/Octokit.Tests.Integration/Reactive/ObservableIssuesClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableIssuesClientTests.cs index 1b40a7ac92..9c6acf9885 100644 --- a/Octokit.Tests.Integration/Reactive/ObservableIssuesClientTests.cs +++ b/Octokit.Tests.Integration/Reactive/ObservableIssuesClientTests.cs @@ -78,15 +78,15 @@ 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); + Assert.False(createResult.Locked); - await _client.LockIssue(_context.RepositoryOwner, _context.RepositoryName, createResult.Number); + await _client.Lock(_context.RepositoryOwner, _context.RepositoryName, createResult.Number); var lockResult = await _client.Get(_context.RepositoryOwner, _context.RepositoryName, createResult.Number); - Assert.Equal(true, lockResult.Locked); + Assert.True(lockResult.Locked); - await _client.UnlockIssue(_context.RepositoryOwner, _context.RepositoryName, createResult.Number); + await _client.Unlock(_context.RepositoryOwner, _context.RepositoryName, createResult.Number); var unlockIssueResult = await _client.Get(_context.RepositoryOwner, _context.RepositoryName, createResult.Number); - Assert.Equal(false, unlockIssueResult.Locked); + Assert.False(unlockIssueResult.Locked); } public void Dispose() diff --git a/Octokit/Clients/IIssuesClient.cs b/Octokit/Clients/IIssuesClient.cs index f6f61dea4a..ed42329e1d 100644 --- a/Octokit/Clients/IIssuesClient.cs +++ b/Octokit/Clients/IIssuesClient.cs @@ -172,7 +172,7 @@ public interface IIssuesClient /// The name of the repository /// The issue number /// - Task LockIssue(string owner, string name, int number); + Task Lock(string owner, string name, int number); /// /// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue. @@ -182,6 +182,6 @@ public interface IIssuesClient /// The name of the repository /// The issue number /// - Task UnlockIssue(string owner, string name, int number); + Task Unlock(string owner, string name, int number); } } diff --git a/Octokit/Clients/IssuesClient.cs b/Octokit/Clients/IssuesClient.cs index be4a9641b6..cb4af64262 100644 --- a/Octokit/Clients/IssuesClient.cs +++ b/Octokit/Clients/IssuesClient.cs @@ -234,12 +234,12 @@ public Task Update(string owner, string name, int number, IssueUpdate iss /// The name of the repository /// The issue number /// - public Task LockIssue(string owner, string name, int number) + public Task Lock(string owner, string name, int number) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(name, "name"); - return ApiConnection.Put(ApiUrls.IssueLock(owner, name, number)); + return ApiConnection.Put(ApiUrls.IssueLock(owner, name, number), AcceptHeaders.IssueLockingUnlockingApiPreview); } /// @@ -250,12 +250,12 @@ public Task LockIssue(string owner, string name, int number) /// The name of the repository /// The issue number /// - public Task UnlockIssue(string owner, string name, int number) + public Task Unlock(string owner, string name, int number) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(name, "name"); - return ApiConnection.Delete(ApiUrls.IssueLock(owner, name, number)); + return ApiConnection.Delete(ApiUrls.IssueLock(owner, name, number), AcceptHeaders.IssueLockingUnlockingApiPreview); } } } diff --git a/Octokit/Helpers/AcceptHeaders.cs b/Octokit/Helpers/AcceptHeaders.cs index d94e7e1502..80310a3619 100644 --- a/Octokit/Helpers/AcceptHeaders.cs +++ b/Octokit/Helpers/AcceptHeaders.cs @@ -13,5 +13,7 @@ public static class AcceptHeaders public const string ProtectedBranchesApiPreview = "application/vnd.github.loki-preview+json"; public const string StarCreationTimestamps = "application/vnd.github.v3.star+json"; + + public const string IssueLockingUnlockingApiPreview = "application/vnd.github.the-key-preview+json"; } } From 55f4e72c2d423f8767e672a382ff9b35f60260ed Mon Sep 17 00:00:00 2001 From: Prayank Mathur Date: Tue, 29 Mar 2016 16:59:55 +0530 Subject: [PATCH 4/7] Changed function names in unit tests --- Octokit.Tests/Clients/IssuesClientTests.cs | 20 ++++++++-------- .../Reactive/ObservableIssuesClientTests.cs | 24 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Octokit.Tests/Clients/IssuesClientTests.cs b/Octokit.Tests/Clients/IssuesClientTests.cs index f4086d6833..2922dba8d8 100644 --- a/Octokit.Tests/Clients/IssuesClientTests.cs +++ b/Octokit.Tests/Clients/IssuesClientTests.cs @@ -193,7 +193,7 @@ public void PostsToCorrectUrl() var connection = Substitute.For(); var client = new IssuesClient(connection); - client.LockIssue("fake", "repo", 42); + client.Lock("fake", "repo", 42); connection.Received().Put(Arg.Is(u => u.ToString() == "repos/fake/repo/issues/42/lock")); } @@ -204,10 +204,10 @@ 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)); + await Assert.ThrowsAsync(() => client.Lock(null, "name", 1)); + await Assert.ThrowsAsync(() => client.Lock("", "name", 1)); + await Assert.ThrowsAsync(() => client.Lock("owner", null, 1)); + await Assert.ThrowsAsync(() => client.Lock("owner", "", 1)); } } @@ -219,7 +219,7 @@ public void PostsToCorrectUrl() var connection = Substitute.For(); var client = new IssuesClient(connection); - client.UnlockIssue("fake", "repo", 42); + client.Unlock("fake", "repo", 42); connection.Received().Delete(Arg.Is(u => u.ToString() == "repos/fake/repo/issues/42/lock")); } @@ -230,10 +230,10 @@ 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)); + await Assert.ThrowsAsync(() => client.Unlock(null, "name", 1)); + await Assert.ThrowsAsync(() => client.Unlock("", "name", 1)); + await Assert.ThrowsAsync(() => client.Unlock("owner", null, 1)); + await Assert.ThrowsAsync(() => client.Unlock("owner", "", 1)); } } diff --git a/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs b/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs index 61afa771cd..9c16f84679 100644 --- a/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs @@ -345,8 +345,8 @@ public void LockIssue() var gitHubClient = Substitute.For(); var client = new ObservableIssuesClient(gitHubClient); - client.LockIssue("fake", "repo", 42); - gitHubClient.Issue.Received().LockIssue("fake", "repo", 42); + client.Lock("fake", "repo", 42); + gitHubClient.Issue.Received().Lock("fake", "repo", 42); } [Fact] @@ -355,10 +355,10 @@ 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)); + Assert.Throws(() => client.Lock(null, "name", 42)); + Assert.Throws(() => client.Lock("", "name", 42)); + Assert.Throws(() => client.Lock("owner", null, 42)); + Assert.Throws(() => client.Lock("owner", "", 42)); } } @@ -370,8 +370,8 @@ public void UnlockIssue() var gitHubClient = Substitute.For(); var client = new ObservableIssuesClient(gitHubClient); - client.UnlockIssue("fake", "repo", 42); - gitHubClient.Issue.Received().UnlockIssue("fake", "repo", 42); + client.Unlock("fake", "repo", 42); + gitHubClient.Issue.Received().Unlock("fake", "repo", 42); } [Fact] @@ -380,10 +380,10 @@ 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)); + Assert.Throws(() => client.Unlock(null, "name", 42)); + Assert.Throws(() => client.Unlock("", "name", 42)); + Assert.Throws(() => client.Unlock("owner", null, 42)); + Assert.Throws(() => client.Unlock("owner", "", 42)); } } From 5173adeffbe5e54d52aa1af5452093a1b7ee23c7 Mon Sep 17 00:00:00 2001 From: Prayank Mathur Date: Tue, 29 Mar 2016 17:13:44 +0530 Subject: [PATCH 5/7] Some more changes in tests --- Octokit.Tests/Clients/IssuesClientTests.cs | 8 ++++---- Octokit.Tests/Reactive/ObservableIssuesClientTests.cs | 8 ++++---- Octokit/Helpers/AcceptHeaders.cs | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Octokit.Tests/Clients/IssuesClientTests.cs b/Octokit.Tests/Clients/IssuesClientTests.cs index 2922dba8d8..ade94e0944 100644 --- a/Octokit.Tests/Clients/IssuesClientTests.cs +++ b/Octokit.Tests/Clients/IssuesClientTests.cs @@ -185,7 +185,7 @@ public async Task EnsuresArgumentsNotNull() } } - public class TheLockIssueMethod + public class TheLockMethod { [Fact] public void PostsToCorrectUrl() @@ -195,7 +195,7 @@ public void PostsToCorrectUrl() client.Lock("fake", "repo", 42); - connection.Received().Put(Arg.Is(u => u.ToString() == "repos/fake/repo/issues/42/lock")); + connection.Received().Put(Arg.Is(u => u.ToString() == "repos/fake/repo/issues/42/lock"), Arg.Is(u => u.ToString() == "application/vnd.github.the-key-preview+json")); } [Fact] @@ -211,7 +211,7 @@ public async Task EnsuresArgumentsNotNull() } } - public class TheUnlockIssueMethod + public class TheUnlockMethod { [Fact] public void PostsToCorrectUrl() @@ -221,7 +221,7 @@ public void PostsToCorrectUrl() client.Unlock("fake", "repo", 42); - connection.Received().Delete(Arg.Is(u => u.ToString() == "repos/fake/repo/issues/42/lock")); + connection.Received().Delete(Arg.Is(u => u.ToString() == "repos/fake/repo/issues/42/lock"), Arg.Is(u => u.ToString() == "application/vnd.github.the-key-preview+json")); } [Fact] diff --git a/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs b/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs index 9c16f84679..c511b90175 100644 --- a/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableIssuesClientTests.cs @@ -337,10 +337,10 @@ public void EnsuresArgumentsNotNull() } } - public class TheLockIssueMethod + public class TheLockMethod { [Fact] - public void LockIssue() + public void LocksIssue() { var gitHubClient = Substitute.For(); var client = new ObservableIssuesClient(gitHubClient); @@ -362,10 +362,10 @@ public void EnsuresArgumentsNotNull() } } - public class TheUnlockIssueMethod + public class TheUnlockMethod { [Fact] - public void UnlockIssue() + public void UnlocksIssue() { var gitHubClient = Substitute.For(); var client = new ObservableIssuesClient(gitHubClient); diff --git a/Octokit/Helpers/AcceptHeaders.cs b/Octokit/Helpers/AcceptHeaders.cs index 4108ddcffd..bf3423b340 100644 --- a/Octokit/Helpers/AcceptHeaders.cs +++ b/Octokit/Helpers/AcceptHeaders.cs @@ -17,6 +17,5 @@ public static class AcceptHeaders public const string IssueLockingUnlockingApiPreview = "application/vnd.github.the-key-preview+json"; public const string CommitReferenceSha1Preview = "application/vnd.github.chitauri-preview+sha"; - } } From 8e49f04a5d3312f193dd0de70701324e0dd8c0d0 Mon Sep 17 00:00:00 2001 From: Prayank Mathur Date: Wed, 30 Mar 2016 14:30:37 +0530 Subject: [PATCH 6/7] Added implementation for delete that takes custom media type header and changed definition for Unlock accordingly --- .../Clients/IssuesClientTests.cs | 7 +++---- Octokit/Clients/IIssuesClient.cs | 2 +- Octokit/Clients/IssuesClient.cs | 6 +++--- Octokit/Http/ApiConnection.cs | 15 +++++++++++++++ Octokit/Http/Connection.cs | 16 ++++++++++++++++ Octokit/Http/IApiConnection.cs | 9 +++++++++ Octokit/Http/IConnection.cs | 9 +++++++++ 7 files changed, 56 insertions(+), 8 deletions(-) diff --git a/Octokit.Tests.Integration/Clients/IssuesClientTests.cs b/Octokit.Tests.Integration/Clients/IssuesClientTests.cs index 118cc73c75..c9619a4bef 100644 --- a/Octokit.Tests.Integration/Clients/IssuesClientTests.cs +++ b/Octokit.Tests.Integration/Clients/IssuesClientTests.cs @@ -65,18 +65,17 @@ 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.False(issue.Locked); await _issuesClient.Lock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); - 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.True(issue.Locked); + Assert.True(retrieved.Locked); await _issuesClient.Unlock(_context.RepositoryOwner, _context.RepositoryName, issue.Number); retrieved = await _issuesClient.Get(_context.RepositoryOwner, _context.RepositoryName, issue.Number); Assert.NotNull(retrieved); - Assert.False(issue.Locked); + Assert.False(retrieved.Locked); } [IntegrationTest] diff --git a/Octokit/Clients/IIssuesClient.cs b/Octokit/Clients/IIssuesClient.cs index ed42329e1d..bea894bfdf 100644 --- a/Octokit/Clients/IIssuesClient.cs +++ b/Octokit/Clients/IIssuesClient.cs @@ -172,7 +172,7 @@ public interface IIssuesClient /// The name of the repository /// The issue number /// - Task Lock(string owner, string name, int number); + Task Lock(string owner, string name, int number); /// /// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue. diff --git a/Octokit/Clients/IssuesClient.cs b/Octokit/Clients/IssuesClient.cs index cb4af64262..4757c01403 100644 --- a/Octokit/Clients/IssuesClient.cs +++ b/Octokit/Clients/IssuesClient.cs @@ -234,12 +234,12 @@ public Task Update(string owner, string name, int number, IssueUpdate iss /// The name of the repository /// The issue number /// - public Task Lock(string owner, string name, int number) + public Task Lock(string owner, string name, int number) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(name, "name"); - return ApiConnection.Put(ApiUrls.IssueLock(owner, name, number), AcceptHeaders.IssueLockingUnlockingApiPreview); + return ApiConnection.Put(ApiUrls.IssueLock(owner, name, number), new object(), null, AcceptHeaders.IssueLockingUnlockingApiPreview); } /// @@ -255,7 +255,7 @@ public Task Unlock(string owner, string name, int number) Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(name, "name"); - return ApiConnection.Delete(ApiUrls.IssueLock(owner, name, number), AcceptHeaders.IssueLockingUnlockingApiPreview); + return ApiConnection.Delete(ApiUrls.IssueLock(owner, name, number), new object(), AcceptHeaders.IssueLockingUnlockingApiPreview); } } } diff --git a/Octokit/Http/ApiConnection.cs b/Octokit/Http/ApiConnection.cs index 0cf57496e0..a08a8aebd6 100644 --- a/Octokit/Http/ApiConnection.cs +++ b/Octokit/Http/ApiConnection.cs @@ -467,6 +467,21 @@ public Task Delete(Uri uri, object data) return Connection.Delete(uri, data); } + /// + /// Performs an asynchronous HTTP DELETE request that expects an empty response. + /// + /// URI endpoint to send request to + /// The object to serialize as the body of the request + /// Specifies accept response media type + /// The returned + public Task Delete(Uri uri, object data, string accepts) + { + Ensure.ArgumentNotNull(uri, "uri"); + Ensure.ArgumentNotNull(data, "data"); + Ensure.ArgumentNotNull(accepts, "accepts"); + + return Connection.Delete(uri, data, accepts); + } /// /// Executes a GET to the API object at the specified URI. This operation is appropriate for /// API calls which wants to return the redirect URL. diff --git a/Octokit/Http/Connection.cs b/Octokit/Http/Connection.cs index 81a1f86bce..dc5bccf2bc 100644 --- a/Octokit/Http/Connection.cs +++ b/Octokit/Http/Connection.cs @@ -484,6 +484,22 @@ public async Task Delete(Uri uri, object data) return response.HttpResponse.StatusCode; } + /// + /// Performs an asynchronous HTTP DELETE request that expects an empty response. + /// + /// URI endpoint to send request to + /// The object to serialize as the body of the request + /// Specifies accept response media type + /// The returned + public async Task Delete(Uri uri,object data, string accepts) + { + Ensure.ArgumentNotNull(uri, "uri"); + Ensure.ArgumentNotNull(accepts, "accepts"); + + var response = await SendData(uri, HttpMethod.Delete, data, accepts, null, CancellationToken.None); + return response.HttpResponse.StatusCode; + } + /// /// Base address for the connection. /// diff --git a/Octokit/Http/IApiConnection.cs b/Octokit/Http/IApiConnection.cs index 81966a101e..f3fe9f20db 100644 --- a/Octokit/Http/IApiConnection.cs +++ b/Octokit/Http/IApiConnection.cs @@ -293,6 +293,15 @@ public interface IApiConnection /// A for the request's execution. Task Delete(Uri uri, object data); + /// + /// Performs an asynchronous HTTP DELETE request that expects an empty response. + /// + /// URI endpoint to send request to + /// The object to serialize as the body of the request + /// Specifies accept response media type + /// The returned + Task Delete(Uri uri, object data, string accepts); + /// /// Executes a GET to the API object at the specified URI. This operation is appropriate for /// API calls which wants to return the redirect URL. diff --git a/Octokit/Http/IConnection.cs b/Octokit/Http/IConnection.cs index 137f488ee2..74b0ab0a60 100644 --- a/Octokit/Http/IConnection.cs +++ b/Octokit/Http/IConnection.cs @@ -234,6 +234,15 @@ public interface IConnection : IApiInfoProvider /// The returned Task Delete(Uri uri, object data); + /// + /// Performs an asynchronous HTTP DELETE request that expects an empty response. + /// + /// URI endpoint to send request to + /// The object to serialize as the body of the request + /// Specifies accept response media type + /// The returned + Task Delete(Uri uri, object data, string accepts); + /// /// Base address for the connection. /// From 73240390ca42f9148f52815673a604db6425fb22 Mon Sep 17 00:00:00 2001 From: Prayank Mathur Date: Wed, 30 Mar 2016 14:42:47 +0530 Subject: [PATCH 7/7] Minor fixes --- Octokit.Reactive/Clients/IObservableIssuesClient.cs | 2 +- Octokit.Reactive/Clients/ObservableIssuesClient.cs | 2 +- Octokit.Tests/Clients/IssuesClientTests.cs | 4 ++-- SolutionInfo.cs | 6 ++---- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Octokit.Reactive/Clients/IObservableIssuesClient.cs b/Octokit.Reactive/Clients/IObservableIssuesClient.cs index 86bbe89de8..d9ca53a334 100644 --- a/Octokit.Reactive/Clients/IObservableIssuesClient.cs +++ b/Octokit.Reactive/Clients/IObservableIssuesClient.cs @@ -166,7 +166,7 @@ public interface IObservableIssuesClient /// The name of the repository /// The issue number /// - IObservable Lock(string owner, string name, int number); + IObservable Lock(string owner, string name, int number); /// /// Unlocks an issue for the specified repository. Issue owners and users with push access can unlock an issue. diff --git a/Octokit.Reactive/Clients/ObservableIssuesClient.cs b/Octokit.Reactive/Clients/ObservableIssuesClient.cs index f00095d346..007b743db4 100644 --- a/Octokit.Reactive/Clients/ObservableIssuesClient.cs +++ b/Octokit.Reactive/Clients/ObservableIssuesClient.cs @@ -232,7 +232,7 @@ public IObservable Update(string owner, string name, int number, IssueUpd /// The name of the repository /// The issue number /// - public IObservable Lock(string owner, string name, int number) + public IObservable Lock(string owner, string name, int number) { Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); Ensure.ArgumentNotNullOrEmptyString(name, "name"); diff --git a/Octokit.Tests/Clients/IssuesClientTests.cs b/Octokit.Tests/Clients/IssuesClientTests.cs index ade94e0944..bcb14395f9 100644 --- a/Octokit.Tests/Clients/IssuesClientTests.cs +++ b/Octokit.Tests/Clients/IssuesClientTests.cs @@ -195,7 +195,7 @@ public void PostsToCorrectUrl() client.Lock("fake", "repo", 42); - connection.Received().Put(Arg.Is(u => u.ToString() == "repos/fake/repo/issues/42/lock"), Arg.Is(u => u.ToString() == "application/vnd.github.the-key-preview+json")); + connection.Received().Put(Arg.Is(u => u.ToString() == "repos/fake/repo/issues/42/lock"), Arg.Any(), Arg.Any(), Arg.Is(u => u.ToString() == "application/vnd.github.the-key-preview+json")); } [Fact] @@ -221,7 +221,7 @@ public void PostsToCorrectUrl() client.Unlock("fake", "repo", 42); - connection.Received().Delete(Arg.Is(u => u.ToString() == "repos/fake/repo/issues/42/lock"), Arg.Is(u => u.ToString() == "application/vnd.github.the-key-preview+json")); + connection.Received().Delete(Arg.Is(u => u.ToString() == "repos/fake/repo/issues/42/lock"), Arg.Any(), Arg.Is(u => u.ToString() == "application/vnd.github.the-key-preview+json")); } [Fact] diff --git a/SolutionInfo.cs b/SolutionInfo.cs index 22509412fb..a52961be74 100644 --- a/SolutionInfo.cs +++ b/SolutionInfo.cs @@ -6,10 +6,8 @@ [assembly: AssemblyVersionAttribute("0.19.0")] [assembly: AssemblyFileVersionAttribute("0.19.0")] [assembly: ComVisibleAttribute(false)] -namespace System -{ - internal static class AssemblyVersionInformation - { +namespace System { + internal static class AssemblyVersionInformation { internal const string Version = "0.19.0"; } }