From 04efc495840e699a6f5b7096732a81b1ad96a16f Mon Sep 17 00:00:00 2001 From: tasadar2 Date: Tue, 10 Apr 2018 11:59:24 -0400 Subject: [PATCH 1/5] Added get release by tag endpoint --- .../Clients/IObservableReleasesClient.cs | 13 ++++++++++++ .../Clients/ObservableReleasesClient.cs | 19 ++++++++++++++++++ Octokit.Tests/Clients/ReleasesClientTests.cs | 18 +++++++++++++++++ .../Reactive/ObservableReleasesClientTests.cs | 18 +++++++++++++++++ Octokit/Clients/IReleasesClient.cs | 12 +++++++++++ Octokit/Clients/ReleasesClient.cs | 20 +++++++++++++++++++ Octokit/Helpers/ApiUrls.cs | 12 +++++++++++ 7 files changed, 112 insertions(+) diff --git a/Octokit.Reactive/Clients/IObservableReleasesClient.cs b/Octokit.Reactive/Clients/IObservableReleasesClient.cs index ec56e379e4..7a9e8023c6 100644 --- a/Octokit.Reactive/Clients/IObservableReleasesClient.cs +++ b/Octokit.Reactive/Clients/IObservableReleasesClient.cs @@ -69,6 +69,19 @@ public interface IObservableReleasesClient [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", Justification = "Method makes a network request")] IObservable Get(string owner, string name, int id); + /// + /// Gets a single for the specified repository. + /// + /// + /// See the API documentation for more information. + /// + /// The repository's owner + /// The repository's name + /// The tag of the release + /// Thrown when a general API error occurs. + [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", Justification = "Method makes a network request")] + IObservable Get(string owner, string name, string tag); + /// /// Gets a single for the specified repository. /// diff --git a/Octokit.Reactive/Clients/ObservableReleasesClient.cs b/Octokit.Reactive/Clients/ObservableReleasesClient.cs index 25d6abb3df..c1f58fd516 100644 --- a/Octokit.Reactive/Clients/ObservableReleasesClient.cs +++ b/Octokit.Reactive/Clients/ObservableReleasesClient.cs @@ -107,6 +107,25 @@ public IObservable Get(string owner, string name, int id) return _client.Get(owner, name, id).ToObservable(); } + /// + /// Gets a single for the specified repository. + /// + /// + /// See the API documentation for more information. + /// + /// The repository's owner + /// The repository's name + /// The tag of the release + /// Thrown when a general API error occurs. + public IObservable Get(string owner, string name, string tag) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); + Ensure.ArgumentNotNullOrEmptyString(tag, nameof(tag)); + + return _client.Get(owner, name, tag).ToObservable(); + } + /// /// Gets a single for the specified repository. /// diff --git a/Octokit.Tests/Clients/ReleasesClientTests.cs b/Octokit.Tests/Clients/ReleasesClientTests.cs index 09a2c49ac0..93e982c89f 100644 --- a/Octokit.Tests/Clients/ReleasesClientTests.cs +++ b/Octokit.Tests/Clients/ReleasesClientTests.cs @@ -123,6 +123,17 @@ public async Task RequestsTheCorrectUrl() connection.Received().Get(Arg.Is(u => u.ToString() == "repos/fake/repo/releases/1")); } + [Fact] + public async Task RequestsTheCorrectUrlByTag() + { + var connection = Substitute.For(); + var client = new ReleasesClient(connection); + + await client.Get("fake", "repo", "tag"); + + connection.Received().Get(Arg.Is(u => u.ToString() == "repos/fake/repo/releases/tags/tag")); + } + [Fact] public async Task RequestsTheCorrectUrlWithRepositoryId() { @@ -144,6 +155,13 @@ public async Task EnsuresNonNullArguments() await Assert.ThrowsAsync(() => releasesClient.Get("", "name", 1)); await Assert.ThrowsAsync(() => releasesClient.Get("owner", "", 1)); + + await Assert.ThrowsAsync(() => releasesClient.Get("owner", "name", null)); + await Assert.ThrowsAsync(() => releasesClient.Get("owner", "name", "")); + await Assert.ThrowsAsync(() => releasesClient.Get(null, "name", "tag")); + await Assert.ThrowsAsync(() => releasesClient.Get("", "name", "tag")); + await Assert.ThrowsAsync(() => releasesClient.Get("owner", null, "tag")); + await Assert.ThrowsAsync(() => releasesClient.Get("owner", "", "tag")); } } diff --git a/Octokit.Tests/Reactive/ObservableReleasesClientTests.cs b/Octokit.Tests/Reactive/ObservableReleasesClientTests.cs index 7d85c5ae13..5bb59957c6 100644 --- a/Octokit.Tests/Reactive/ObservableReleasesClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableReleasesClientTests.cs @@ -126,6 +126,17 @@ public void RequestsTheCorrectUrlWithRepositoryId() gitHubClient.Repository.Release.Received(1).Get(1, 1); } + [Fact] + public void RequestsTheCorrectUrlWithTag() + { + var gitHubClient = Substitute.For(); + var client = new ObservableReleasesClient(gitHubClient); + + client.Get("fake", "repo", "tag"); + + gitHubClient.Repository.Release.Received(1).Get("fake", "repo", "tag"); + } + [Fact] public void EnsuresNonNullArguments() { @@ -136,6 +147,13 @@ public void EnsuresNonNullArguments() Assert.Throws(() => releasesClient.Get("", "name", 1)); Assert.Throws(() => releasesClient.Get("owner", "", 1)); + + Assert.Throws(() => releasesClient.Get(null, "name", "tag")); + Assert.Throws(() => releasesClient.Get("", "name", "tag")); + Assert.Throws(() => releasesClient.Get("owner", null, "tag")); + Assert.Throws(() => releasesClient.Get("owner", "", "tag")); + Assert.Throws(() => releasesClient.Get("owner", "name", null)); + Assert.Throws(() => releasesClient.Get("owner", "name", "")); } } diff --git a/Octokit/Clients/IReleasesClient.cs b/Octokit/Clients/IReleasesClient.cs index 46293ecc66..03eaa6bfec 100644 --- a/Octokit/Clients/IReleasesClient.cs +++ b/Octokit/Clients/IReleasesClient.cs @@ -69,6 +69,18 @@ public interface IReleasesClient [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", Justification = "Method makes a network request")] Task Get(string owner, string name, int id); + /// + /// Gets a single for the specified repository. + /// + /// + /// See the API documentation for more information. + /// + /// The repository's owner + /// The repository's name + /// The tag of the release + /// Thrown when a general API error occurs. + Task Get(string owner, string name, string tag); + /// /// Gets a single for the specified repository. /// diff --git a/Octokit/Clients/ReleasesClient.cs b/Octokit/Clients/ReleasesClient.cs index 804df0222e..6430b0bc5a 100644 --- a/Octokit/Clients/ReleasesClient.cs +++ b/Octokit/Clients/ReleasesClient.cs @@ -105,6 +105,26 @@ public Task Get(string owner, string name, int id) return ApiConnection.Get(endpoint); } + /// + /// Gets a single for the specified repository. + /// + /// + /// See the API documentation for more information. + /// + /// The repository's owner + /// The repository's name + /// The tag of the release + /// Thrown when a general API error occurs. + public Task Get(string owner, string name, string tag) + { + Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner)); + Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); + Ensure.ArgumentNotNullOrEmptyString(tag, nameof(tag)); + + var endpoint = ApiUrls.Releases(owner, name, tag); + return ApiConnection.Get(endpoint); + } + /// /// Gets a single for the specified repository. /// diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index 2b5154f038..63cd304420 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -215,6 +215,18 @@ public static Uri Releases(string owner, string name, int id) return "repos/{0}/{1}/releases/{2}".FormatUri(owner, name, id); } + /// + /// Returns the that returns a single release for the specified repository + /// + /// The owner of the repository + /// The name of the repository + /// The tag of the release + /// + public static Uri Releases(string owner, string name, string tag) + { + return "repos/{0}/{1}/releases/tags/{2}".FormatUri(owner, name, tag); + } + /// /// Returns the that returns the latest release for the specified repository /// From 2edc1c62b4b60cc13dcc76cc2afd503095a2c234 Mon Sep 17 00:00:00 2001 From: tasadar2 Date: Wed, 11 Apr 2018 19:06:57 -0400 Subject: [PATCH 2/5] Added integration tests for get release by tag overload --- .../Clients/ReleasesClientTests.cs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/Octokit.Tests.Integration/Clients/ReleasesClientTests.cs b/Octokit.Tests.Integration/Clients/ReleasesClientTests.cs index b06f4cfc10..6a8daa369b 100644 --- a/Octokit.Tests.Integration/Clients/ReleasesClientTests.cs +++ b/Octokit.Tests.Integration/Clients/ReleasesClientTests.cs @@ -168,6 +168,44 @@ public void Dispose() } } + public class TheGetReleaseByTagMethod + { + private readonly IReleasesClient _releaseClient; + private readonly IGitHubClient _client; + + public TheGetReleaseByTagMethod() + { + _client = Helper.GetAuthenticatedClient(); + _releaseClient = _client.Repository.Release; + } + + [IntegrationTest] + public async Task ReturnsLatestRelease() + { + var lastReleaseFromGetAll = (await _releaseClient.GetAll("octokit", "octokit.net")).OrderBy(r => r.CreatedAt).Last(); + var releaseByTag = await _releaseClient.Get("octokit", "octokit.net", lastReleaseFromGetAll.TagName); + + Assert.Equal(lastReleaseFromGetAll.Id, releaseByTag.Id); + } + + [IntegrationTest] + public async Task NoReleaseOnRepo() + { + var repoName = Helper.MakeNameWithTimestamp("public-repo"); + await _client.Repository.Create(new NewRepository(repoName)); + + await Assert.ThrowsAsync(() => _releaseClient.Get(Helper.UserName, repoName, "0.0")); + + await _client.Repository.Delete(Helper.UserName, repoName); + } + + [IntegrationTest] + public async Task NoReleaseWithTag() + { + await Assert.ThrowsAsync(() => _releaseClient.Get("octokit", "octokit.net", "0.0")); + } + } + public class TheGetAllMethod { readonly IReleasesClient _releaseClient; From c9685000528991a769efbe2b0e6e503db9c60bc4 Mon Sep 17 00:00:00 2001 From: Ryan Gribble Date: Thu, 12 Apr 2018 21:23:59 +1000 Subject: [PATCH 3/5] tidy up integration tests and add reactive integration tests --- .../Clients/ReleasesClientTests.cs | 26 ++++++----------- .../Reactive/ObservableReleaseClientTests.cs | 28 +++++++++++++++++++ .../Reactive/ObservableReleasesClientTests.cs | 2 +- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/Octokit.Tests.Integration/Clients/ReleasesClientTests.cs b/Octokit.Tests.Integration/Clients/ReleasesClientTests.cs index 6a8daa369b..e277042fbe 100644 --- a/Octokit.Tests.Integration/Clients/ReleasesClientTests.cs +++ b/Octokit.Tests.Integration/Clients/ReleasesClientTests.cs @@ -168,39 +168,29 @@ public void Dispose() } } - public class TheGetReleaseByTagMethod + public class TheGetMethod { private readonly IReleasesClient _releaseClient; private readonly IGitHubClient _client; - public TheGetReleaseByTagMethod() + public TheGetMethod() { _client = Helper.GetAuthenticatedClient(); _releaseClient = _client.Repository.Release; } [IntegrationTest] - public async Task ReturnsLatestRelease() - { - var lastReleaseFromGetAll = (await _releaseClient.GetAll("octokit", "octokit.net")).OrderBy(r => r.CreatedAt).Last(); - var releaseByTag = await _releaseClient.Get("octokit", "octokit.net", lastReleaseFromGetAll.TagName); - - Assert.Equal(lastReleaseFromGetAll.Id, releaseByTag.Id); - } - - [IntegrationTest] - public async Task NoReleaseOnRepo() + public async Task ReturnsReleaseByTag() { - var repoName = Helper.MakeNameWithTimestamp("public-repo"); - await _client.Repository.Create(new NewRepository(repoName)); - - await Assert.ThrowsAsync(() => _releaseClient.Get(Helper.UserName, repoName, "0.0")); + var releaseByTag = await _releaseClient.Get("octokit", "octokit.net", "v0.28.0"); - await _client.Repository.Delete(Helper.UserName, repoName); + Assert.Equal(releaseByTag.Id, 8396883); + Assert.Equal(releaseByTag.Name, "v0.28 - Get to the Chopper!!!"); + Assert.Equal(releaseByTag.TagName, "v0.28.0"); } [IntegrationTest] - public async Task NoReleaseWithTag() + public async Task ThrowsWhenTagNotFound() { await Assert.ThrowsAsync(() => _releaseClient.Get("octokit", "octokit.net", "0.0")); } diff --git a/Octokit.Tests.Integration/Reactive/ObservableReleaseClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableReleaseClientTests.cs index 337f2894d5..9ab9ba1995 100644 --- a/Octokit.Tests.Integration/Reactive/ObservableReleaseClientTests.cs +++ b/Octokit.Tests.Integration/Reactive/ObservableReleaseClientTests.cs @@ -84,5 +84,33 @@ public async Task ReturnsDistinctResultsBasedOnStartPage() Assert.NotEqual(firstPage[4].Id, secondPage[4].Id); } } + + public class TheGetMethod + { + readonly ObservableReleasesClient _releaseClient; + + public TheGetMethod() + { + var github = Helper.GetAuthenticatedClient(); + + _releaseClient = new ObservableReleasesClient(github); + } + + [IntegrationTest] + public async Task ReturnsReleaseByTag() + { + var releaseByTag = await _releaseClient.Get("octokit", "octokit.net", "v0.28.0"); + + Assert.Equal(releaseByTag.Id, 8396883); + Assert.Equal(releaseByTag.Name, "v0.28 - Get to the Chopper!!!"); + Assert.Equal(releaseByTag.TagName, "v0.28.0"); + } + + [IntegrationTest] + public async Task ThrowsWhenTagNotFound() + { + await Assert.ThrowsAsync(async () => await _releaseClient.Get("octokit", "octokit.net", "0.0")); + } + } } } diff --git a/Octokit.Tests/Reactive/ObservableReleasesClientTests.cs b/Octokit.Tests/Reactive/ObservableReleasesClientTests.cs index 5bb59957c6..636744708b 100644 --- a/Octokit.Tests/Reactive/ObservableReleasesClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableReleasesClientTests.cs @@ -127,7 +127,7 @@ public void RequestsTheCorrectUrlWithRepositoryId() } [Fact] - public void RequestsTheCorrectUrlWithTag() + public void RequestsTheCorrectUrlByTag() { var gitHubClient = Substitute.For(); var client = new ObservableReleasesClient(gitHubClient); From 13086157aad67e07070aeb2c2a6c521bd909e98a Mon Sep 17 00:00:00 2001 From: Ryan Gribble Date: Thu, 12 Apr 2018 21:51:04 +1000 Subject: [PATCH 4/5] Implement repositoryId based method --- .../Clients/ReleasesClientTests.cs | 16 ++++++++++++++++ Octokit.Tests/Clients/ReleasesClientTests.cs | 14 ++++++++++++++ Octokit/Clients/IReleasesClient.cs | 13 +++++++++++-- Octokit/Clients/ReleasesClient.cs | 17 +++++++++++++++++ Octokit/Helpers/ApiUrls.cs | 11 +++++++++++ 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/Octokit.Tests.Integration/Clients/ReleasesClientTests.cs b/Octokit.Tests.Integration/Clients/ReleasesClientTests.cs index e277042fbe..176fd9245b 100644 --- a/Octokit.Tests.Integration/Clients/ReleasesClientTests.cs +++ b/Octokit.Tests.Integration/Clients/ReleasesClientTests.cs @@ -189,11 +189,27 @@ public async Task ReturnsReleaseByTag() Assert.Equal(releaseByTag.TagName, "v0.28.0"); } + [IntegrationTest] + public async Task ReturnsReleaseWithRepositoryIdByTag() + { + var releaseByTag = await _releaseClient.Get(7528679, "v0.28.0"); + + Assert.Equal(releaseByTag.Id, 8396883); + Assert.Equal(releaseByTag.Name, "v0.28 - Get to the Chopper!!!"); + Assert.Equal(releaseByTag.TagName, "v0.28.0"); + } + [IntegrationTest] public async Task ThrowsWhenTagNotFound() { await Assert.ThrowsAsync(() => _releaseClient.Get("octokit", "octokit.net", "0.0")); } + + [IntegrationTest] + public async Task ThrowsWhenTagNotFoundWithRepositoryId() + { + await Assert.ThrowsAsync(() => _releaseClient.Get(7528679, "0.0")); + } } public class TheGetAllMethod diff --git a/Octokit.Tests/Clients/ReleasesClientTests.cs b/Octokit.Tests/Clients/ReleasesClientTests.cs index 93e982c89f..db25679e88 100644 --- a/Octokit.Tests/Clients/ReleasesClientTests.cs +++ b/Octokit.Tests/Clients/ReleasesClientTests.cs @@ -145,6 +145,17 @@ public async Task RequestsTheCorrectUrlWithRepositoryId() connection.Received().Get(Arg.Is(u => u.ToString() == "repositories/1/releases/1")); } + [Fact] + public async Task RequestsTheCorrectUrlWithRepositoryIdByTag() + { + var connection = Substitute.For(); + var client = new ReleasesClient(connection); + + await client.Get(1, "tag"); + + connection.Received().Get(Arg.Is(u => u.ToString() == "repositories/1/releases/tags/tag")); + } + [Fact] public async Task EnsuresNonNullArguments() { @@ -162,6 +173,9 @@ public async Task EnsuresNonNullArguments() await Assert.ThrowsAsync(() => releasesClient.Get("", "name", "tag")); await Assert.ThrowsAsync(() => releasesClient.Get("owner", null, "tag")); await Assert.ThrowsAsync(() => releasesClient.Get("owner", "", "tag")); + + await Assert.ThrowsAsync(() => releasesClient.Get(1, null)); + await Assert.ThrowsAsync(() => releasesClient.Get(1, "")); } } diff --git a/Octokit/Clients/IReleasesClient.cs b/Octokit/Clients/IReleasesClient.cs index 03eaa6bfec..56a700a23c 100644 --- a/Octokit/Clients/IReleasesClient.cs +++ b/Octokit/Clients/IReleasesClient.cs @@ -66,7 +66,6 @@ public interface IReleasesClient /// The repository's name /// The id of the release /// Thrown when a general API error occurs. - [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", Justification = "Method makes a network request")] Task Get(string owner, string name, int id); /// @@ -90,9 +89,19 @@ public interface IReleasesClient /// The Id of the repository /// The id of the release /// Thrown when a general API error occurs. - [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", Justification = "Method makes a network request")] Task Get(long repositoryId, int id); + /// + /// Gets a single for the specified repository. + /// + /// + /// See the API documentation for more information. + /// + /// The Id of the repository + /// The tag of the release + /// Thrown when a general API error occurs. + Task Get(long repositoryId, string tag); + /// /// Gets the latest for the specified repository. /// diff --git a/Octokit/Clients/ReleasesClient.cs b/Octokit/Clients/ReleasesClient.cs index 6430b0bc5a..7dd95ebafb 100644 --- a/Octokit/Clients/ReleasesClient.cs +++ b/Octokit/Clients/ReleasesClient.cs @@ -140,6 +140,23 @@ public Task Get(long repositoryId, int id) return ApiConnection.Get(endpoint); } + /// + /// Gets a single for the specified repository. + /// + /// + /// See the API documentation for more information. + /// + /// The Id of the repository + /// The tag of the release + /// Thrown when a general API error occurs. + public Task Get(long repositoryId, string tag) + { + Ensure.ArgumentNotNullOrEmptyString(tag, nameof(tag)); + + var endpoint = ApiUrls.Releases(repositoryId, tag); + return ApiConnection.Get(endpoint); + } + /// /// Gets the latest for the specified repository. /// diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index 63cd304420..a97a7fbd0c 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -3052,6 +3052,17 @@ public static Uri Releases(long repositoryId, int id) return "repositories/{0}/releases/{1}".FormatUri(repositoryId, id); } + /// + /// Returns the that returns a single release for the specified repository + /// + /// The Id of the repository + /// The tag of the release + /// The that returns a single release for the specified repository + public static Uri Releases(long repositoryId, string tag) + { + return "repositories/{0}/releases/tags/{1}".FormatUri(repositoryId, tag); + } + /// /// Returns the for a repository branch. /// From 580c88ef75dcda77842074e105dca0216bd86c46 Mon Sep 17 00:00:00 2001 From: Ryan Gribble Date: Thu, 12 Apr 2018 21:51:19 +1000 Subject: [PATCH 5/5] Implement repositoryId based method in Reactive client --- .../Clients/IObservableReleasesClient.cs | 14 +++++++++++--- .../Clients/ObservableReleasesClient.cs | 16 ++++++++++++++++ .../Reactive/ObservableReleaseClientTests.cs | 16 ++++++++++++++++ .../Reactive/ObservableReleasesClientTests.cs | 11 +++++++++++ 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/Octokit.Reactive/Clients/IObservableReleasesClient.cs b/Octokit.Reactive/Clients/IObservableReleasesClient.cs index 7a9e8023c6..b4a2b2a200 100644 --- a/Octokit.Reactive/Clients/IObservableReleasesClient.cs +++ b/Octokit.Reactive/Clients/IObservableReleasesClient.cs @@ -66,7 +66,6 @@ public interface IObservableReleasesClient /// The repository's name /// The id of the release /// Thrown when a general API error occurs. - [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", Justification = "Method makes a network request")] IObservable Get(string owner, string name, int id); /// @@ -79,7 +78,6 @@ public interface IObservableReleasesClient /// The repository's name /// The tag of the release /// Thrown when a general API error occurs. - [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", Justification = "Method makes a network request")] IObservable Get(string owner, string name, string tag); /// @@ -91,9 +89,19 @@ public interface IObservableReleasesClient /// The Id of the repository /// The id of the release /// Thrown when a general API error occurs. - [SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", Justification = "Method makes a network request")] IObservable Get(long repositoryId, int id); + /// + /// Gets a single for the specified repository. + /// + /// + /// See the API documentation for more information. + /// + /// The Id of the repository + /// The tag of the release + /// Thrown when a general API error occurs. + IObservable Get(long repositoryId, string tag); + /// /// Gets the latest for the specified repository. /// diff --git a/Octokit.Reactive/Clients/ObservableReleasesClient.cs b/Octokit.Reactive/Clients/ObservableReleasesClient.cs index c1f58fd516..b9568e56dc 100644 --- a/Octokit.Reactive/Clients/ObservableReleasesClient.cs +++ b/Octokit.Reactive/Clients/ObservableReleasesClient.cs @@ -140,6 +140,22 @@ public IObservable Get(long repositoryId, int id) return _client.Get(repositoryId, id).ToObservable(); } + /// + /// Gets a single for the specified repository. + /// + /// + /// See the API documentation for more information. + /// + /// The Id of the repository + /// The tag of the release + /// Thrown when a general API error occurs. + public IObservable Get(long repositoryId, string tag) + { + Ensure.ArgumentNotNullOrEmptyString(tag, nameof(tag)); + + return _client.Get(repositoryId, tag).ToObservable(); + } + /// /// Gets the latest for the specified repository. /// diff --git a/Octokit.Tests.Integration/Reactive/ObservableReleaseClientTests.cs b/Octokit.Tests.Integration/Reactive/ObservableReleaseClientTests.cs index 9ab9ba1995..c706704b1a 100644 --- a/Octokit.Tests.Integration/Reactive/ObservableReleaseClientTests.cs +++ b/Octokit.Tests.Integration/Reactive/ObservableReleaseClientTests.cs @@ -106,11 +106,27 @@ public async Task ReturnsReleaseByTag() Assert.Equal(releaseByTag.TagName, "v0.28.0"); } + [IntegrationTest] + public async Task ReturnsReleaseWithRepositoryIdByTag() + { + var releaseByTag = await _releaseClient.Get(7528679, "v0.28.0"); + + Assert.Equal(releaseByTag.Id, 8396883); + Assert.Equal(releaseByTag.Name, "v0.28 - Get to the Chopper!!!"); + Assert.Equal(releaseByTag.TagName, "v0.28.0"); + } + [IntegrationTest] public async Task ThrowsWhenTagNotFound() { await Assert.ThrowsAsync(async () => await _releaseClient.Get("octokit", "octokit.net", "0.0")); } + + [IntegrationTest] + public async Task ThrowsWhenTagNotFoundWithRepositoryId() + { + await Assert.ThrowsAsync(async () => await _releaseClient.Get(7528679, "0.0")); + } } } } diff --git a/Octokit.Tests/Reactive/ObservableReleasesClientTests.cs b/Octokit.Tests/Reactive/ObservableReleasesClientTests.cs index 636744708b..438bd1fe91 100644 --- a/Octokit.Tests/Reactive/ObservableReleasesClientTests.cs +++ b/Octokit.Tests/Reactive/ObservableReleasesClientTests.cs @@ -137,6 +137,17 @@ public void RequestsTheCorrectUrlByTag() gitHubClient.Repository.Release.Received(1).Get("fake", "repo", "tag"); } + [Fact] + public void RequestsTheCorrectUrlWithRepositoryIdByTag() + { + var gitHubClient = Substitute.For(); + var client = new ObservableReleasesClient(gitHubClient); + + client.Get(1, "tag"); + + gitHubClient.Repository.Release.Received(1).Get(1, "tag"); + } + [Fact] public void EnsuresNonNullArguments() {