diff --git a/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj b/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj index 0d91a136..2e2ddae2 100644 --- a/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj +++ b/Octokit.Tests.Integration/Octokit.Tests.Integration.csproj @@ -49,6 +49,7 @@ + diff --git a/Octokit.Tests.Integration/ReleasesClientTests.cs b/Octokit.Tests.Integration/ReleasesClientTests.cs new file mode 100644 index 00000000..8dcd7f91 --- /dev/null +++ b/Octokit.Tests.Integration/ReleasesClientTests.cs @@ -0,0 +1,26 @@ +using System.Linq; +using System.Threading.Tasks; +using Xunit; + +namespace Octokit.Tests.Integration +{ + public class ReleasesClientTests + { + public class TheGetReleasesMethod + { + [IntegrationTest] + public async Task ReturnsReleases() + { + var github = new GitHubClient + { + Credentials = AutomationSettings.Current.GitHubCredentials + }; + + var releases = await github.Releases.GetAll("git-tfs", "git-tfs"); + + Assert.True(releases.Count > 5); + Assert.True(releases.Any(release => release.TagName == "v0.18.0")); + } + } + } +} diff --git a/Octokit.Tests.Integration/RepositoriesClientTests.cs b/Octokit.Tests.Integration/RepositoriesClientTests.cs index b599e9d0..92157975 100644 --- a/Octokit.Tests.Integration/RepositoriesClientTests.cs +++ b/Octokit.Tests.Integration/RepositoriesClientTests.cs @@ -90,22 +90,5 @@ namespace Octokit.Tests.Integration Assert.Contains("

WARNING: This is some haacky code.", readMeHtml); } } - - public class TheGetReleasesMethod - { - [IntegrationTest] - public async Task ReturnsReleases() - { - var github = new GitHubClient - { - Credentials = AutomationSettings.Current.GitHubCredentials - }; - - var releases = await github.Repository.GetReleases("git-tfs", "git-tfs"); - - Assert.True(releases.Count > 5); - Assert.True(releases.Any(release => release.TagName == "v0.18.0")); - } - } } } diff --git a/Octokit.Tests/Clients/ReleasesClientTests.cs b/Octokit.Tests/Clients/ReleasesClientTests.cs new file mode 100644 index 00000000..2ab3ffc1 --- /dev/null +++ b/Octokit.Tests/Clients/ReleasesClientTests.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using NSubstitute; +using Octokit.Clients; +using Octokit.Http; +using Octokit.Tests.Helpers; +using Xunit; + +namespace Octokit.Tests.Clients +{ + public class ReleasesClientTests + { + + public class TheGetReleasesMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var client = Substitute.For>(); + var releasesClient = new ReleasesClient(client); + + releasesClient.GetAll("fake", "repo"); + + client.Received().GetAll(Arg.Is(u => u.ToString() == "/repos/fake/repo/releases"), null); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var releasesClient = new ReleasesClient(Substitute.For>()); + + await AssertEx.Throws(async () => await releasesClient.GetAll(null, "name")); + await AssertEx.Throws(async () => await releasesClient.GetAll("owner", null)); + } + } + + public class TheCreateReleaseMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var client = Substitute.For>(); + var releasesClient = new ReleasesClient(client); + var data = new ReleaseUpdate("fake-tag"); + + releasesClient.CreateRelease("fake", "repo", data); + + client.Received().Create(Arg.Is(u => u.ToString() == "/repos/fake/repo/releases"), data); + } + + [Fact] + public async Task EnsuresArgumentsNotNull() + { + var releasesClient = new ReleasesClient(Substitute.For>()); + var data = new ReleaseUpdate("fake-tag"); + + Assert.Throws(() => new ReleaseUpdate(null)); + await AssertEx.Throws(async () => await releasesClient.CreateRelease(null, "name", data)); + await AssertEx.Throws(async () => await releasesClient.CreateRelease("owner", null, data)); + await AssertEx.Throws(async () => await releasesClient.CreateRelease("owner", "name", null)); + } + } + + public class TheUploadReleaseAssetMethod + { + [Fact] + public void UploadsToCorrectUrl() + { + var client = Substitute.For>(); + var releasesClient = new ReleasesClient(client); + var release = new Release { UploadUrl = "https://uploads.test.dev/does/not/matter/releases/1/assets{?name}" }; + var rawData = Substitute.For(); + var upload = new ReleaseAssetUpload { FileName = "example.zip", ContentType = "application/zip", RawData = rawData }; + + releasesClient.UploadAsset(release, upload); + + client.Received().Upload(Arg.Is(u => u.ToString() == "https://uploads.test.dev/does/not/matter/releases/1/assets?name=example.zip"), + rawData, + Arg.Is>(headers => headers["Content-Type"] == "application/zip")); + } + + [Fact] + public async Task EnsuresArgumentsNotNull() + { + var releasesClient = new ReleasesClient(Substitute.For>()); + + var release = new Release { UploadUrl = "https://uploads.github.com/anything" }; + var uploadData = new ReleaseAssetUpload { FileName = "good", ContentType = "good/good", RawData = Stream.Null }; + await AssertEx.Throws(async () => await releasesClient.UploadAsset(null, uploadData)); + await AssertEx.Throws(async () => await releasesClient.UploadAsset(release, null)); + } + } + } +} diff --git a/Octokit.Tests/Clients/RepositoriesClientTests.cs b/Octokit.Tests/Clients/RepositoriesClientTests.cs index ac18d560..0504b6d5 100644 --- a/Octokit.Tests/Clients/RepositoriesClientTests.cs +++ b/Octokit.Tests/Clients/RepositoriesClientTests.cs @@ -141,85 +141,5 @@ namespace Octokit.Tests.Clients client.Received().GetHtml(Arg.Is(u => u.ToString() == "https://github.example.com/readme"), null); } } - - public class TheGetReleasesMethod - { - [Fact] - public void RequestsCorrectUrl() - { - var client = Substitute.For>(); - var repositoriesClient = new RepositoriesClient(client); - - repositoriesClient.GetReleases("fake", "repo"); - - client.Received().GetAll(Arg.Is(u => u.ToString() == "/repos/fake/repo/releases"), null); - } - - [Fact] - public async Task EnsuresNonNullArguments() - { - var repositoriesClient = new RepositoriesClient(Substitute.For>()); - - await AssertEx.Throws(async () => await repositoriesClient.GetReleases(null, "name")); - await AssertEx.Throws(async () => await repositoriesClient.GetReleases("owner", null)); - } - } - - public class TheCreateReleaseMethod - { - [Fact] - public void RequestsCorrectUrl() - { - var client = Substitute.For>(); - var repositoriesClient = new RepositoriesClient(client); - var data = new ReleaseUpdate("fake-tag"); - - repositoriesClient.CreateRelease("fake", "repo", data); - - client.Received().Create(Arg.Is(u => u.ToString() == "/repos/fake/repo/releases"), data); - } - - [Fact] - public async Task EnsuresArgumentsNotNull() - { - var repositoriesClient = new RepositoriesClient(Substitute.For>()); - var data = new ReleaseUpdate("fake-tag"); - - Assert.Throws(() => new ReleaseUpdate(null)); - await AssertEx.Throws(async () => await repositoriesClient.CreateRelease(null, "name", data)); - await AssertEx.Throws(async () => await repositoriesClient.CreateRelease("owner", null, data)); - await AssertEx.Throws(async () => await repositoriesClient.CreateRelease("owner", "name", null)); - } - } - - public class TheUploadReleaseAssetMethod - { - [Fact] - public void UploadsToCorrectUrl() - { - var client = Substitute.For>(); - var repositoriesClient = new RepositoriesClient(client); - var release = new Release { UploadUrl = "https://uploads.test.dev/does/not/matter/releases/1/assets{?name}" }; - var rawData = Substitute.For(); - var upload = new ReleaseAssetUpload { FileName = "example.zip", ContentType = "application/zip", RawData = rawData }; - - repositoriesClient.UploadAsset(release, upload); - - client.Received().Upload(Arg.Is(u => u.ToString() == "https://uploads.test.dev/does/not/matter/releases/1/assets?name=example.zip"), - rawData, - Arg.Is>(headers => headers["Content-Type"] == "application/zip")); - } - - [Fact] - public async Task EnsuresArgumentsNotNull() - { - var repositoriesClient = new RepositoriesClient(Substitute.For>()); - - var release = new Release { UploadUrl = "https://uploads.github.com/anything" }; - var uploadData = new ReleaseAssetUpload { FileName = "good", ContentType = "good/good", RawData = Stream.Null }; - await AssertEx.Throws(async () => await repositoriesClient.UploadAsset(null, uploadData)); - await AssertEx.Throws(async () => await repositoriesClient.UploadAsset(release, null)); - } - } } } diff --git a/Octokit.Tests/Octokit.Tests.csproj b/Octokit.Tests/Octokit.Tests.csproj index d0fba100..235256d6 100644 --- a/Octokit.Tests/Octokit.Tests.csproj +++ b/Octokit.Tests/Octokit.Tests.csproj @@ -51,6 +51,7 @@ + diff --git a/Octokit/Clients/ReleasesClient.cs b/Octokit/Clients/ReleasesClient.cs new file mode 100644 index 00000000..8c340f4e --- /dev/null +++ b/Octokit/Clients/ReleasesClient.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Octokit.Http; + +namespace Octokit.Clients +{ + public class ReleasesClient : ApiClient, IReleasesClient + { + public ReleasesClient(IApiConnection client) : base(client) + { + } + + public async Task> GetAll(string owner, string name) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(name, "repository"); + + var endpoint = "/repos/{0}/{1}/releases".FormatUri(owner, name); + return await Client.GetAll(endpoint); + } + + + public async Task CreateRelease(string owner, string name, ReleaseUpdate data) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(name, "repository"); + Ensure.ArgumentNotNull(data, "data"); + + var endpoint = "/repos/{0}/{1}/releases".FormatUri(owner, name); + return await Client.Create(endpoint, data); + } + + + public async Task UploadAsset(Release release, ReleaseAssetUpload data) + { + Ensure.ArgumentNotNull(release, "release"); + Ensure.ArgumentNotNull(data, "data"); + + var endpoint = release.UploadUrl.ExpandUriTemplate(new { name = data.FileName }); + return await Client.Upload(endpoint, data.RawData, new Dictionary { { "Content-Type", data.ContentType }, { "Accept", "application/vnd.github.manifold-preview" } }); + } + } +} diff --git a/Octokit/Clients/RepositoriesClient.cs b/Octokit/Clients/RepositoriesClient.cs index 1808b3e4..e09e0dbb 100644 --- a/Octokit/Clients/RepositoriesClient.cs +++ b/Octokit/Clients/RepositoriesClient.cs @@ -53,35 +53,5 @@ namespace Octokit.Clients var readmeInfo = await Client.GetItem(endpoint, null); return new Readme(readmeInfo, Client); } - - public async Task> GetReleases(string owner, string name) - { - Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); - Ensure.ArgumentNotNullOrEmptyString(name, "repository"); - - var endpoint = "/repos/{0}/{1}/releases".FormatUri(owner, name); - return await Client.GetAll(endpoint); - } - - - public async Task CreateRelease(string owner, string name, ReleaseUpdate data) - { - Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); - Ensure.ArgumentNotNullOrEmptyString(name, "repository"); - Ensure.ArgumentNotNull(data, "data"); - - var endpoint = "/repos/{0}/{1}/releases".FormatUri(owner, name); - return await Client.Create(endpoint, data); - } - - - public async Task UploadAsset(Release release, ReleaseAssetUpload data) - { - Ensure.ArgumentNotNull(release, "release"); - Ensure.ArgumentNotNull(data, "data"); - - var endpoint = release.UploadUrl.ExpandUriTemplate(new { name = data.FileName }); - return await Client.Upload(endpoint, data.RawData, new Dictionary { { "Content-Type", data.ContentType }, { "Accept", "application/vnd.github.manifold-preview" } }); - } } } diff --git a/Octokit/GitHubClient.cs b/Octokit/GitHubClient.cs index d11a6a9b..0399e50e 100644 --- a/Octokit/GitHubClient.cs +++ b/Octokit/GitHubClient.cs @@ -39,6 +39,7 @@ namespace Octokit AutoComplete = new AutoCompleteClient(connection); Organization = new OrganizationsClient(new ApiConnection(connection)); Repository = new RepositoriesClient(new ApiConnection(connection)); + Releases = new ReleasesClient(new ApiConnection(connection)); User = new UsersClient(new ApiConnection(connection)); SshKey = new SshKeysClient(new ApiConnection(connection)); } @@ -79,6 +80,7 @@ namespace Octokit public IAutoCompleteClient AutoComplete { get; private set; } public IOrganizationsClient Organization { get; private set; } public IRepositoriesClient Repository { get; private set; } + public IReleasesClient Releases { get; private set; } public ISshKeysClient SshKey { get; private set; } public IUsersClient User { get; private set; } } diff --git a/Octokit/IReleasesClient.cs b/Octokit/IReleasesClient.cs new file mode 100644 index 00000000..6be68490 --- /dev/null +++ b/Octokit/IReleasesClient.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + public interface IReleasesClient + { + ///

+ /// Retrieves every for the specified repository. + /// + /// The owner of the repository. + /// The name of the repository. + /// A of . + Task> GetAll(string owner, string name); + + /// + /// Create a for the specified repository. + /// + /// The owner of the repository. + /// The name of the repository. + /// The data for the release. + /// A new . + Task CreateRelease(string owner, string name, ReleaseUpdate data); + + /// + /// Upload a for the specified release. + /// + /// The to attach the asset to. + /// The asset information. + /// A new . + Task UploadAsset(Release release, ReleaseAssetUpload data); + } +} diff --git a/Octokit/IRepositoriesClient.cs b/Octokit/IRepositoriesClient.cs index ad3e133d..41200131 100644 --- a/Octokit/IRepositoriesClient.cs +++ b/Octokit/IRepositoriesClient.cs @@ -57,30 +57,5 @@ namespace Octokit /// The name of the repository. /// Task GetReadme(string owner, string name); - - /// - /// Retrieves every for the specified repository. - /// - /// The owner of the repository. - /// The name of the repository. - /// A of . - Task> GetReleases(string owner, string name); - - /// - /// Create a for the specified repository. - /// - /// The owner of the repository. - /// The name of the repository. - /// The data for the release. - /// A new . - Task CreateRelease(string owner, string name, ReleaseUpdate data); - - /// - /// Upload a for the specified release. - /// - /// The to attach the asset to. - /// The asset information. - /// A new . - Task UploadAsset(Release release, ReleaseAssetUpload data); } } diff --git a/Octokit/Octokit.csproj b/Octokit/Octokit.csproj index dd4104b5..1672bee8 100644 --- a/Octokit/Octokit.csproj +++ b/Octokit/Octokit.csproj @@ -86,6 +86,7 @@ + @@ -106,6 +107,7 @@ + diff --git a/Octokit/OctokitRT.csproj b/Octokit/OctokitRT.csproj index 3e9254aa..1b1519f0 100644 --- a/Octokit/OctokitRT.csproj +++ b/Octokit/OctokitRT.csproj @@ -110,6 +110,7 @@ + @@ -153,6 +154,7 @@ +