From f771147f1d4f6f3a582f45aadeb39ea98754e5fa Mon Sep 17 00:00:00 2001 From: tasadar2 Date: Tue, 8 May 2018 07:49:52 -0400 Subject: [PATCH] Added a pre-receive environments client (#1796) * Added pre-receive environment client https://developer.github.com/v3/enterprise-admin/pre_receive_environments * Added unit and integration tests for the pre-receive environments client * moved test setup outside of tests * fixed unit test * Added reactive components for pre-receive environment endpoints * Debugger display's and non public setters on response object conventions * removed redundant parameter attributes implemented update request independently of new request changed ints to longs for future proofing updated unit tests changed update integration tests to create a new update request to ensure optional values function * updating reactive environmentids to longs as well * also converting response id to a long * Fixed an incorrect unit test renamed some test variable names for consistency Added mockable ctors on responses, and parameterless ctors to maintain functionality * Adding missing state parameter * rename client member accessor to singular form in accordance with octokit naming conventions * fixup tests * add integration tests for observable client --- .../Enterprise/IObservableEnterpriseClient.cs | 8 + ...eEnterprisePreReceiveEnvironmentsClient.cs | 100 +++++ .../Enterprise/ObservableEnterpriseClient.cs | 9 + ...eEnterprisePreReceiveEnvironmentsClient.cs | 143 +++++++ ...rprisePreReceiveEnvironmentsClientTests.cs | 349 +++++++++++++++++ Octokit.Tests.Integration/EnterpriseHelper.cs | 38 ++ ...rprisePreReceiveEnvironmentsClientTests.cs | 351 ++++++++++++++++++ ...rprisePreReceiveEnvironmentsClientTests.cs | 179 +++++++++ ...rprisePreReceiveEnvironmentsClientTests.cs | 177 +++++++++ .../Clients/Enterprise/EnterpriseClient.cs | 9 + .../EnterprisePreReceiveEnvironmentsClient.cs | 143 +++++++ .../Clients/Enterprise/IEnterpriseClient.cs | 8 + ...IEnterprisePreReceiveEnvironmentsClient.cs | 100 +++++ Octokit/Helpers/AcceptHeaders.cs | 2 + Octokit/Helpers/ApiUrls.cs | 36 ++ .../Enterprise/NewPreReceiveEnvironment.cs | 41 ++ .../Enterprise/UpdatePreReceiveEnvironment.cs | 27 ++ .../Enterprise/PreReceiveEnvironment.cs | 92 +++++ .../PreReceiveEnvironmentDownload.cs | 49 +++ .../PreReceiveEnvironmentDownloadState.cs | 22 ++ 20 files changed, 1883 insertions(+) create mode 100644 Octokit.Reactive/Clients/Enterprise/IObservableEnterprisePreReceiveEnvironmentsClient.cs create mode 100644 Octokit.Reactive/Clients/Enterprise/ObservableEnterprisePreReceiveEnvironmentsClient.cs create mode 100644 Octokit.Tests.Integration/Clients/Enterprise/EnterprisePreReceiveEnvironmentsClientTests.cs create mode 100644 Octokit.Tests.Integration/Reactive/Enterprise/ObservableEnterprisePreReceiveEnvironmentsClientTests.cs create mode 100644 Octokit.Tests/Clients/Enterprise/EnterprisePreReceiveEnvironmentsClientTests.cs create mode 100644 Octokit.Tests/Reactive/Enterprise/ObservableEnterprisePreReceiveEnvironmentsClientTests.cs create mode 100644 Octokit/Clients/Enterprise/EnterprisePreReceiveEnvironmentsClient.cs create mode 100644 Octokit/Clients/Enterprise/IEnterprisePreReceiveEnvironmentsClient.cs create mode 100644 Octokit/Models/Request/Enterprise/NewPreReceiveEnvironment.cs create mode 100644 Octokit/Models/Request/Enterprise/UpdatePreReceiveEnvironment.cs create mode 100644 Octokit/Models/Response/Enterprise/PreReceiveEnvironment.cs create mode 100644 Octokit/Models/Response/Enterprise/PreReceiveEnvironmentDownload.cs create mode 100644 Octokit/Models/Response/Enterprise/PreReceiveEnvironmentDownloadState.cs diff --git a/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseClient.cs b/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseClient.cs index 018c48e8..27a7d1a2 100644 --- a/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseClient.cs +++ b/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseClient.cs @@ -47,5 +47,13 @@ /// See the Enterprise Search Indexing API documentation for more information. /// IObservableEnterpriseSearchIndexingClient SearchIndexing { get; } + + /// + /// A client for GitHub's Enterprise Pre-receive Environments API + /// + /// + /// See the Enterprise Pre-receive Environments API documentation for more information. + /// + IObservableEnterprisePreReceiveEnvironmentsClient PreReceiveEnvironment { get; } } } diff --git a/Octokit.Reactive/Clients/Enterprise/IObservableEnterprisePreReceiveEnvironmentsClient.cs b/Octokit.Reactive/Clients/Enterprise/IObservableEnterprisePreReceiveEnvironmentsClient.cs new file mode 100644 index 00000000..2bc29fa2 --- /dev/null +++ b/Octokit.Reactive/Clients/Enterprise/IObservableEnterprisePreReceiveEnvironmentsClient.cs @@ -0,0 +1,100 @@ +using System; +using System.Reactive; + +namespace Octokit.Reactive +{ + /// + /// A client for GitHub's Enterprise Pre-receive Environments API + /// + /// + /// See the Enterprise Pre-receive Environments API documentation for more information. + /// + public interface IObservableEnterprisePreReceiveEnvironmentsClient + { + /// + /// Gets all s. + /// + /// + /// See the API documentation for more information. + /// + /// Thrown when a general API error occurs. + IObservable GetAll(); + + /// + /// Gets all s. + /// + /// + /// See the API documentation for more information. + /// + /// Options for changing the API response + /// Thrown when a general API error occurs. + IObservable GetAll(ApiOptions options); + + /// + /// Gets a single . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + IObservable Get(long environmentId); + + /// + /// Creates a new . + /// + /// + /// See the API documentation for more information. + /// + /// A description of the pre-receive environment to create + /// Thrown when a general API error occurs. + IObservable Create(NewPreReceiveEnvironment newPreReceiveEnvironment); + + /// + /// Edits an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// A description of the pre-receive environment to edit + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + IObservable Edit(long environmentId, UpdatePreReceiveEnvironment updatePreReceiveEnvironment); + + /// + /// Deletes an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + IObservable Delete(long environmentId); + + /// + /// Gets the download status for an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + IObservable DownloadStatus(long environmentId); + + /// + /// Triggers a new download of the 's tarball from the environment's . + /// When the download is finished, the newly downloaded tarball will overwrite the existing environment. + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + IObservable TriggerDownload(long environmentId); + } +} diff --git a/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseClient.cs b/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseClient.cs index 25ba9c22..067e81cf 100644 --- a/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseClient.cs +++ b/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseClient.cs @@ -17,6 +17,7 @@ License = new ObservableEnterpriseLicenseClient(client); Organization = new ObservableEnterpriseOrganizationClient(client); SearchIndexing = new ObservableEnterpriseSearchIndexingClient(client); + PreReceiveEnvironment = new ObservableEnterprisePreReceiveEnvironmentsClient(client); } /// @@ -58,5 +59,13 @@ /// See the Enterprise Search Indexing API documentation for more information. /// public IObservableEnterpriseSearchIndexingClient SearchIndexing { get; private set; } + + /// + /// A client for GitHub's Enterprise Pre-receive Environments API + /// + /// + /// See the Enterprise Pre-receive Environments API documentation for more information. + /// + public IObservableEnterprisePreReceiveEnvironmentsClient PreReceiveEnvironment { get; private set; } } } diff --git a/Octokit.Reactive/Clients/Enterprise/ObservableEnterprisePreReceiveEnvironmentsClient.cs b/Octokit.Reactive/Clients/Enterprise/ObservableEnterprisePreReceiveEnvironmentsClient.cs new file mode 100644 index 00000000..f49b337c --- /dev/null +++ b/Octokit.Reactive/Clients/Enterprise/ObservableEnterprisePreReceiveEnvironmentsClient.cs @@ -0,0 +1,143 @@ +using System; +using System.Reactive; +using System.Reactive.Threading.Tasks; +using Octokit.Reactive.Internal; + +namespace Octokit.Reactive +{ + /// + /// A client for GitHub's Enterprise Pre-receive Environments API + /// + /// + /// See the Enterprise Pre-receive Environments API documentation for more information. + /// + public class ObservableEnterprisePreReceiveEnvironmentsClient : IObservableEnterprisePreReceiveEnvironmentsClient + { + readonly IEnterprisePreReceiveEnvironmentsClient _client; + readonly IConnection _connection; + + public ObservableEnterprisePreReceiveEnvironmentsClient(IGitHubClient client) + { + Ensure.ArgumentNotNull(client, nameof(client)); + + _client = client.Enterprise.PreReceiveEnvironment; + _connection = client.Connection; + } + + /// + /// Gets all s. + /// + /// + /// See the API documentation for more information. + /// + /// Thrown when a general API error occurs. + public IObservable GetAll() + { + return GetAll(ApiOptions.None); + } + + /// + /// Gets all s. + /// + /// + /// See the API documentation for more information. + /// + /// Options for changing the API response + /// Thrown when a general API error occurs. + public IObservable GetAll(ApiOptions options) + { + Ensure.ArgumentNotNull(options, nameof(options)); + + return _connection.GetAndFlattenAllPages(ApiUrls.AdminPreReceiveEnvironments(), null, AcceptHeaders.PreReceiveEnvironmentsPreview, options); + } + + /// + /// Gets a single . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public IObservable Get(long environmentId) + { + return _client.Get(environmentId).ToObservable(); + } + + /// + /// Creates a new . + /// + /// + /// See the API documentation for more information. + /// + /// A description of the pre-receive environment to create + /// Thrown when a general API error occurs. + public IObservable Create(NewPreReceiveEnvironment newPreReceiveEnvironment) + { + Ensure.ArgumentNotNull(newPreReceiveEnvironment, nameof(newPreReceiveEnvironment)); + + return _client.Create(newPreReceiveEnvironment).ToObservable(); + } + + /// + /// Edits an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// A description of the pre-receive environment to edit + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public IObservable Edit(long environmentId, UpdatePreReceiveEnvironment updatePreReceiveEnvironment) + { + Ensure.ArgumentNotNull(updatePreReceiveEnvironment, nameof(updatePreReceiveEnvironment)); + + return _client.Edit(environmentId, updatePreReceiveEnvironment).ToObservable(); + } + + /// + /// Deletes an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public IObservable Delete(long environmentId) + { + return _client.Delete(environmentId).ToObservable(); + } + + /// + /// Gets the download status for an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public IObservable DownloadStatus(long environmentId) + { + return _client.DownloadStatus(environmentId).ToObservable(); + } + + /// + /// Triggers a new download of the 's tarball from the environment's . + /// When the download is finished, the newly downloaded tarball will overwrite the existing environment. + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public IObservable TriggerDownload(long environmentId) + { + return _client.TriggerDownload(environmentId).ToObservable(); + } + } +} diff --git a/Octokit.Tests.Integration/Clients/Enterprise/EnterprisePreReceiveEnvironmentsClientTests.cs b/Octokit.Tests.Integration/Clients/Enterprise/EnterprisePreReceiveEnvironmentsClientTests.cs new file mode 100644 index 00000000..211ee905 --- /dev/null +++ b/Octokit.Tests.Integration/Clients/Enterprise/EnterprisePreReceiveEnvironmentsClientTests.cs @@ -0,0 +1,349 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Octokit; +using Octokit.Tests.Integration; +using Xunit; + +public class EnterprisePreReceiveEnvironmentsClientTests +{ + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new EnterprisePreReceiveEnvironmentsClient(null)); + } + } + + public class TheGetAllMethod : IDisposable + { + private readonly IGitHubClient _githubEnterprise; + private readonly IEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + private readonly List _preReceiveEnvironments; + + public TheGetAllMethod() + { + _githubEnterprise = EnterpriseHelper.GetAuthenticatedClient(); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + + _preReceiveEnvironments = new List(); + for (var count = 0; count < 5; count++) + { + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(Helper.MakeNameWithTimestamp("pre-receive"), "https://example.com/foo.zip"); + _preReceiveEnvironments.Add(_preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment).Result); + } + } + + [GitHubEnterpriseTest] + public async Task ReturnsPreReceiveEnvironments() + { + var preReceiveEnvironments = await _preReceiveEnvironmentsClient.GetAll(); + + Assert.NotEmpty(preReceiveEnvironments); + } + + [GitHubEnterpriseTest] + public async Task ReturnsCorrectCountOfPreReceiveEnvironmentsWithoutStart() + { + var options = new ApiOptions + { + PageSize = 1, + PageCount = 1 + }; + + var preReceiveEnvironments = await _preReceiveEnvironmentsClient.GetAll(options); + + Assert.Equal(1, preReceiveEnvironments.Count); + } + + [GitHubEnterpriseTest] + public async Task ReturnsCorrectCountOfPreReceiveEnvironmentsWithStart() + { + var options = new ApiOptions + { + PageSize = 1, + PageCount = 1, + StartPage = 2 + }; + + var preReceiveEnvironments = await _preReceiveEnvironmentsClient.GetAll(options); + + Assert.Equal(1, preReceiveEnvironments.Count); + } + + [GitHubEnterpriseTest] + public async Task ReturnsDistinctResultsBasedOnStartPage() + { + var startOptions = new ApiOptions + { + PageSize = 1, + PageCount = 1 + }; + + var firstPage = await _preReceiveEnvironmentsClient.GetAll(startOptions); + + var skipStartOptions = new ApiOptions + { + PageSize = 1, + PageCount = 1, + StartPage = 2 + }; + + var secondPage = await _preReceiveEnvironmentsClient.GetAll(skipStartOptions); + + Assert.NotEqual(firstPage[0].Id, secondPage[0].Id); + } + + public void Dispose() + { + foreach (var preReceiveEnvironment in _preReceiveEnvironments) + { + EnterpriseHelper.DeletePreReceiveEnvironment(_githubEnterprise.Connection, preReceiveEnvironment); + } + } + } + + public class TheGetMethod : IDisposable + { + private readonly string _preReceiveEnvironmentName; + private readonly string _preReceiveEnvironmentUrl; + private readonly IGitHubClient _githubEnterprise; + private readonly IEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + private readonly PreReceiveEnvironment _preReceiveEnvironment; + + public TheGetMethod() + { + _githubEnterprise = EnterpriseHelper.GetAuthenticatedClient(); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + + _preReceiveEnvironmentName = Helper.MakeNameWithTimestamp("pre-receive"); + _preReceiveEnvironmentUrl = "https://example.com/foo.zip"; + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(_preReceiveEnvironmentName, _preReceiveEnvironmentUrl); + _preReceiveEnvironment = _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment).Result; + } + + [GitHubEnterpriseTest] + public async Task ReturnsName() + { + var preReceiveEnvironment = await _preReceiveEnvironmentsClient.Get(_preReceiveEnvironment.Id); + + Assert.NotNull(preReceiveEnvironment); + Assert.Equal(_preReceiveEnvironmentName, preReceiveEnvironment.Name); + } + + [GitHubEnterpriseTest] + public async Task ReturnsImageUrl() + { + var preReceiveEnvironment = await _preReceiveEnvironmentsClient.Get(_preReceiveEnvironment.Id); + + Assert.NotNull(preReceiveEnvironment); + Assert.Equal(_preReceiveEnvironmentUrl, preReceiveEnvironment.ImageUrl); + } + + [GitHubEnterpriseTest] + public async Task NoEnvironmentExists() + { + await Assert.ThrowsAsync(() => _preReceiveEnvironmentsClient.Get(-1)); + } + + public void Dispose() + { + EnterpriseHelper.DeletePreReceiveEnvironment(_githubEnterprise.Connection, _preReceiveEnvironment); + } + } + + public class TheCreateMethod + { + private readonly IGitHubClient _githubEnterprise; + private readonly IEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + + public TheCreateMethod() + { + _githubEnterprise = EnterpriseHelper.GetAuthenticatedClient(); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + } + + [Fact] + public async Task CanCreatePreReceiveEnvironment() + { + PreReceiveEnvironment preReceiveEnvironment = null; + try + { + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(Helper.MakeNameWithTimestamp("pre-receive"), "https://example.com/foo.zip"); + + preReceiveEnvironment = await _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment); + + Assert.NotNull(preReceiveEnvironment); + Assert.Equal(newPreReceiveEnvironment.Name, preReceiveEnvironment.Name); + Assert.Equal(newPreReceiveEnvironment.ImageUrl, preReceiveEnvironment.ImageUrl); + } + finally + { + //Cleanup + EnterpriseHelper.DeletePreReceiveEnvironment(_githubEnterprise.Connection, preReceiveEnvironment); + } + } + + [Fact] + public async Task CannotCreateWithSameName() + { + var newPreReceiveEnvironment = new NewPreReceiveEnvironment("default", "https://example.com/foo.zip"); + + await Assert.ThrowsAsync(() => _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment)); + } + } + + public class TheEditMethod : IDisposable + { + private readonly IGitHubClient _githubEnterprise; + private readonly IEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + private readonly PreReceiveEnvironment _preReceiveEnvironment; + + public TheEditMethod() + { + _githubEnterprise = EnterpriseHelper.GetAuthenticatedClient(); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(Helper.MakeNameWithTimestamp("pre-receive"), "https://example.com/foo.zip"); + _preReceiveEnvironment = _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment).Result; + EnterpriseHelper.WaitForPreReceiveEnvironmentToComplete(_githubEnterprise.Connection, _preReceiveEnvironment); + } + + [GitHubEnterpriseTest] + public async Task CanChangeNameOfPreReceiveEnvironment() + { + var updatePreReceiveEnvironment = new UpdatePreReceiveEnvironment + { + Name = Helper.MakeNameWithTimestamp("pre-receive") + }; + + var updatedPreReceiveEnvironment = await _preReceiveEnvironmentsClient.Edit(_preReceiveEnvironment.Id, updatePreReceiveEnvironment); + + Assert.Equal(_preReceiveEnvironment.Id, updatedPreReceiveEnvironment.Id); + Assert.Equal(updatePreReceiveEnvironment.Name, updatedPreReceiveEnvironment.Name); + Assert.Equal(_preReceiveEnvironment.ImageUrl, updatedPreReceiveEnvironment.ImageUrl); + } + + [GitHubEnterpriseTest] + public async Task CanChangeImageUrlOfPreReceiveEnvironment() + { + var updatePreReceiveEnvironment = new UpdatePreReceiveEnvironment + { + ImageUrl = "https://example.com/bar.zip" + }; + + var updatedPreReceiveEnvironment = await _preReceiveEnvironmentsClient.Edit(_preReceiveEnvironment.Id, updatePreReceiveEnvironment); + + Assert.Equal(_preReceiveEnvironment.Id, updatedPreReceiveEnvironment.Id); + Assert.Equal(updatePreReceiveEnvironment.ImageUrl, updatedPreReceiveEnvironment.ImageUrl); + Assert.Equal(_preReceiveEnvironment.Name, updatedPreReceiveEnvironment.Name); + } + + public void Dispose() + { + EnterpriseHelper.DeletePreReceiveEnvironment(_githubEnterprise.Connection, _preReceiveEnvironment); + } + } + + public class TheDeleteMethod + { + private readonly IGitHubClient _githubEnterprise; + private readonly IEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + + public TheDeleteMethod() + { + _githubEnterprise = EnterpriseHelper.GetAuthenticatedClient(); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + } + + [GitHubEnterpriseTest] + public async Task CanDeletePreReceiveEnvironment() + { + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(Helper.MakeNameWithTimestamp("pre-receive"), "https://example.com/foo.zip"); + var preReceiveEnvironment = await _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment); + EnterpriseHelper.WaitForPreReceiveEnvironmentToComplete(_githubEnterprise.Connection, preReceiveEnvironment); + + await _preReceiveEnvironmentsClient.Delete(preReceiveEnvironment.Id); + + await Assert.ThrowsAsync(async () => await _preReceiveEnvironmentsClient.Get(preReceiveEnvironment.Id)); + } + + [GitHubEnterpriseTest] + public async Task CannotDeleteWhenNoEnvironmentExists() + { + await Assert.ThrowsAsync(async () => await _preReceiveEnvironmentsClient.Delete(-1)); + } + } + + public class TheDownloadStatusMethod : IDisposable + { + private readonly IGitHubClient _githubEnterprise; + private readonly IEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + private readonly PreReceiveEnvironment _preReceiveEnvironment; + + public TheDownloadStatusMethod() + { + _githubEnterprise = EnterpriseHelper.GetAuthenticatedClient(); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(Helper.MakeNameWithTimestamp("pre-receive"), "https://example.com/foo.zip"); + _preReceiveEnvironment = _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment).Result; + } + + [GitHubEnterpriseTest] + public async Task CanGetDownloadStatus() + { + var downloadStatus = await _preReceiveEnvironmentsClient.DownloadStatus(_preReceiveEnvironment.Id); + + Assert.NotNull(downloadStatus); + } + + [GitHubEnterpriseTest] + public async Task CannotGetDownloadStatusWhenNoEnvironmentExists() + { + await Assert.ThrowsAsync(async () => await _preReceiveEnvironmentsClient.DownloadStatus(-1)); + } + + public void Dispose() + { + EnterpriseHelper.DeletePreReceiveEnvironment(_githubEnterprise.Connection, _preReceiveEnvironment); + } + } + + public class TheTriggerDownloadMethod : IDisposable + { + private readonly IGitHubClient _githubEnterprise; + private readonly IEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + private readonly PreReceiveEnvironment _preReceiveEnvironment; + + public TheTriggerDownloadMethod() + { + _githubEnterprise = EnterpriseHelper.GetAuthenticatedClient(); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(Helper.MakeNameWithTimestamp("pre-receive"), "https://example.com/foo.zip"); + _preReceiveEnvironment = _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment).Result; + EnterpriseHelper.WaitForPreReceiveEnvironmentToComplete(_githubEnterprise.Connection, _preReceiveEnvironment); + } + + [GitHubEnterpriseTest] + public async Task CanTriggerDownload() + { + var downloadStatus = await _preReceiveEnvironmentsClient.DownloadStatus(_preReceiveEnvironment.Id); + + Assert.NotNull(downloadStatus); + } + + [GitHubEnterpriseTest] + public async Task CannotTriggerDownloadWhenNoEnvironmentExists() + { + await Assert.ThrowsAsync(async () => await _preReceiveEnvironmentsClient.DownloadStatus(-1)); + } + + public void Dispose() + { + EnterpriseHelper.DeletePreReceiveEnvironment(_githubEnterprise.Connection, _preReceiveEnvironment); + } + } +} diff --git a/Octokit.Tests.Integration/EnterpriseHelper.cs b/Octokit.Tests.Integration/EnterpriseHelper.cs index deae6e0e..6db94379 100644 --- a/Octokit.Tests.Integration/EnterpriseHelper.cs +++ b/Octokit.Tests.Integration/EnterpriseHelper.cs @@ -124,6 +124,44 @@ namespace Octokit.Tests.Integration catch { } } + public static void WaitForPreReceiveEnvironmentToComplete(IConnection connection, PreReceiveEnvironment preReceiveEnvironment) + { + if (preReceiveEnvironment != null) + { + try + { + var client = new GitHubClient(connection); + var downloadStatus = preReceiveEnvironment.Download; + + var sw = Stopwatch.StartNew(); + while (sw.Elapsed < TimeSpan.FromSeconds(15) && (downloadStatus.State == PreReceiveEnvironmentDownloadState.NotStarted || downloadStatus.State == PreReceiveEnvironmentDownloadState.InProgress)) + { + downloadStatus = client.Enterprise.PreReceiveEnvironment.DownloadStatus(preReceiveEnvironment.Id).Result; + } + + sw.Stop(); + } + catch + { } + } + } + + public static void DeletePreReceiveEnvironment(IConnection connection, PreReceiveEnvironment preReceiveEnvironment) + { + if (preReceiveEnvironment != null) + { + WaitForPreReceiveEnvironmentToComplete(connection, preReceiveEnvironment); + + try + { + var client = new GitHubClient(connection); + client.Enterprise.PreReceiveEnvironment.Delete(preReceiveEnvironment.Id).Wait(TimeSpan.FromSeconds(15)); + } + catch + { } + } + } + public static IGitHubClient GetAuthenticatedClient() { return new GitHubClient(new ProductHeaderValue("OctokitEnterpriseTests"), GitHubEnterpriseUrl) diff --git a/Octokit.Tests.Integration/Reactive/Enterprise/ObservableEnterprisePreReceiveEnvironmentsClientTests.cs b/Octokit.Tests.Integration/Reactive/Enterprise/ObservableEnterprisePreReceiveEnvironmentsClientTests.cs new file mode 100644 index 00000000..22e05fa1 --- /dev/null +++ b/Octokit.Tests.Integration/Reactive/Enterprise/ObservableEnterprisePreReceiveEnvironmentsClientTests.cs @@ -0,0 +1,351 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Reactive.Linq; +using Octokit; +using Octokit.Reactive; +using Octokit.Tests.Integration; +using Xunit; + +public class ObservableEnterprisePreReceiveEnvironmentsClientTests +{ + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new EnterprisePreReceiveEnvironmentsClient(null)); + } + } + + public class TheGetAllMethod : IDisposable + { + private readonly IObservableGitHubClient _githubEnterprise; + private readonly IObservableEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + private readonly List _preReceiveEnvironments; + + public TheGetAllMethod() + { + _githubEnterprise = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient()); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + + _preReceiveEnvironments = new List(); + for (var count = 0; count < 5; count++) + { + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(Helper.MakeNameWithTimestamp("pre-receive"), "https://example.com/foo.zip"); + _preReceiveEnvironments.Add(_preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment).Wait()); + } + } + + [GitHubEnterpriseTest] + public async Task ReturnsPreReceiveEnvironments() + { + var preReceiveEnvironments = await _preReceiveEnvironmentsClient.GetAll().ToList(); + + Assert.NotEmpty(preReceiveEnvironments); + } + + [GitHubEnterpriseTest] + public async Task ReturnsCorrectCountOfPreReceiveEnvironmentsWithoutStart() + { + var options = new ApiOptions + { + PageSize = 1, + PageCount = 1 + }; + + var preReceiveEnvironments = await _preReceiveEnvironmentsClient.GetAll(options).ToList(); + + Assert.Equal(1, preReceiveEnvironments.Count); + } + + [GitHubEnterpriseTest] + public async Task ReturnsCorrectCountOfPreReceiveEnvironmentsWithStart() + { + var options = new ApiOptions + { + PageSize = 1, + PageCount = 1, + StartPage = 2 + }; + + var preReceiveEnvironments = await _preReceiveEnvironmentsClient.GetAll(options).ToList(); + + Assert.Equal(1, preReceiveEnvironments.Count); + } + + [GitHubEnterpriseTest] + public async Task ReturnsDistinctResultsBasedOnStartPage() + { + var startOptions = new ApiOptions + { + PageSize = 1, + PageCount = 1 + }; + + var firstPage = await _preReceiveEnvironmentsClient.GetAll(startOptions).ToList(); + + var skipStartOptions = new ApiOptions + { + PageSize = 1, + PageCount = 1, + StartPage = 2 + }; + + var secondPage = await _preReceiveEnvironmentsClient.GetAll(skipStartOptions).ToList(); + + Assert.NotEqual(firstPage[0].Id, secondPage[0].Id); + } + + public void Dispose() + { + foreach (var preReceiveEnvironment in _preReceiveEnvironments) + { + EnterpriseHelper.DeletePreReceiveEnvironment(_githubEnterprise.Connection, preReceiveEnvironment); + } + } + } + + public class TheGetMethod : IDisposable + { + private readonly string _preReceiveEnvironmentName; + private readonly string _preReceiveEnvironmentUrl; + private readonly IObservableGitHubClient _githubEnterprise; + private readonly IObservableEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + private readonly PreReceiveEnvironment _preReceiveEnvironment; + + public TheGetMethod() + { + _githubEnterprise = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient()); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + + _preReceiveEnvironmentName = Helper.MakeNameWithTimestamp("pre-receive"); + _preReceiveEnvironmentUrl = "https://example.com/foo.zip"; + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(_preReceiveEnvironmentName, _preReceiveEnvironmentUrl); + _preReceiveEnvironment = _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment).Wait(); + } + + [GitHubEnterpriseTest] + public async Task ReturnsName() + { + var preReceiveEnvironment = await _preReceiveEnvironmentsClient.Get(_preReceiveEnvironment.Id); + + Assert.NotNull(preReceiveEnvironment); + Assert.Equal(_preReceiveEnvironmentName, preReceiveEnvironment.Name); + } + + [GitHubEnterpriseTest] + public async Task ReturnsImageUrl() + { + var preReceiveEnvironment = await _preReceiveEnvironmentsClient.Get(_preReceiveEnvironment.Id); + + Assert.NotNull(preReceiveEnvironment); + Assert.Equal(_preReceiveEnvironmentUrl, preReceiveEnvironment.ImageUrl); + } + + [GitHubEnterpriseTest] + public async Task NoEnvironmentExists() + { + await Assert.ThrowsAsync(async () => await _preReceiveEnvironmentsClient.Get(-1)); + } + + public void Dispose() + { + EnterpriseHelper.DeletePreReceiveEnvironment(_githubEnterprise.Connection, _preReceiveEnvironment); + } + } + + public class TheCreateMethod + { + private readonly IObservableGitHubClient _githubEnterprise; + private readonly IObservableEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + + public TheCreateMethod() + { + _githubEnterprise = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient()); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + } + + [Fact] + public async Task CanCreatePreReceiveEnvironment() + { + PreReceiveEnvironment preReceiveEnvironment = null; + try + { + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(Helper.MakeNameWithTimestamp("pre-receive"), "https://example.com/foo.zip"); + + preReceiveEnvironment = await _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment); + + Assert.NotNull(preReceiveEnvironment); + Assert.Equal(newPreReceiveEnvironment.Name, preReceiveEnvironment.Name); + Assert.Equal(newPreReceiveEnvironment.ImageUrl, preReceiveEnvironment.ImageUrl); + } + finally + { + //Cleanup + EnterpriseHelper.DeletePreReceiveEnvironment(_githubEnterprise.Connection, preReceiveEnvironment); + } + } + + [Fact] + public async Task CannotCreateWithSameName() + { + var newPreReceiveEnvironment = new NewPreReceiveEnvironment("default", "https://example.com/foo.zip"); + + await Assert.ThrowsAsync(async () => await _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment)); + } + } + + public class TheEditMethod : IDisposable + { + private readonly IObservableGitHubClient _githubEnterprise; + private readonly IObservableEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + private readonly PreReceiveEnvironment _preReceiveEnvironment; + + public TheEditMethod() + { + _githubEnterprise = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient()); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(Helper.MakeNameWithTimestamp("pre-receive"), "https://example.com/foo.zip"); + _preReceiveEnvironment = _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment).Wait(); + EnterpriseHelper.WaitForPreReceiveEnvironmentToComplete(_githubEnterprise.Connection, _preReceiveEnvironment); + } + + [GitHubEnterpriseTest] + public async Task CanChangeNameOfPreReceiveEnvironment() + { + var updatePreReceiveEnvironment = new UpdatePreReceiveEnvironment + { + Name = Helper.MakeNameWithTimestamp("pre-receive") + }; + + var updatedPreReceiveEnvironment = await _preReceiveEnvironmentsClient.Edit(_preReceiveEnvironment.Id, updatePreReceiveEnvironment); + + Assert.Equal(_preReceiveEnvironment.Id, updatedPreReceiveEnvironment.Id); + Assert.Equal(updatePreReceiveEnvironment.Name, updatedPreReceiveEnvironment.Name); + Assert.Equal(_preReceiveEnvironment.ImageUrl, updatedPreReceiveEnvironment.ImageUrl); + } + + [GitHubEnterpriseTest] + public async Task CanChangeImageUrlOfPreReceiveEnvironment() + { + var updatePreReceiveEnvironment = new UpdatePreReceiveEnvironment + { + ImageUrl = "https://example.com/bar.zip" + }; + + var updatedPreReceiveEnvironment = await _preReceiveEnvironmentsClient.Edit(_preReceiveEnvironment.Id, updatePreReceiveEnvironment); + + Assert.Equal(_preReceiveEnvironment.Id, updatedPreReceiveEnvironment.Id); + Assert.Equal(updatePreReceiveEnvironment.ImageUrl, updatedPreReceiveEnvironment.ImageUrl); + Assert.Equal(_preReceiveEnvironment.Name, updatedPreReceiveEnvironment.Name); + } + + public void Dispose() + { + EnterpriseHelper.DeletePreReceiveEnvironment(_githubEnterprise.Connection, _preReceiveEnvironment); + } + } + + public class TheDeleteMethod + { + private readonly IObservableGitHubClient _githubEnterprise; + private readonly IObservableEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + + public TheDeleteMethod() + { + _githubEnterprise = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient()); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + } + + [GitHubEnterpriseTest] + public async Task CanDeletePreReceiveEnvironment() + { + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(Helper.MakeNameWithTimestamp("pre-receive"), "https://example.com/foo.zip"); + var preReceiveEnvironment = await _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment); + EnterpriseHelper.WaitForPreReceiveEnvironmentToComplete(_githubEnterprise.Connection, preReceiveEnvironment); + + await _preReceiveEnvironmentsClient.Delete(preReceiveEnvironment.Id); + + await Assert.ThrowsAsync(async () => await _preReceiveEnvironmentsClient.Get(preReceiveEnvironment.Id)); + } + + [GitHubEnterpriseTest] + public async Task CannotDeleteWhenNoEnvironmentExists() + { + await Assert.ThrowsAsync(async () => await _preReceiveEnvironmentsClient.Delete(-1)); + } + } + + public class TheDownloadStatusMethod : IDisposable + { + private readonly IObservableGitHubClient _githubEnterprise; + private readonly IObservableEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + private readonly PreReceiveEnvironment _preReceiveEnvironment; + + public TheDownloadStatusMethod() + { + _githubEnterprise = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient()); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(Helper.MakeNameWithTimestamp("pre-receive"), "https://example.com/foo.zip"); + _preReceiveEnvironment = _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment).Wait(); + } + + [GitHubEnterpriseTest] + public async Task CanGetDownloadStatus() + { + var downloadStatus = await _preReceiveEnvironmentsClient.DownloadStatus(_preReceiveEnvironment.Id); + + Assert.NotNull(downloadStatus); + } + + [GitHubEnterpriseTest] + public async Task CannotGetDownloadStatusWhenNoEnvironmentExists() + { + await Assert.ThrowsAsync(async () => await _preReceiveEnvironmentsClient.DownloadStatus(-1)); + } + + public void Dispose() + { + EnterpriseHelper.DeletePreReceiveEnvironment(_githubEnterprise.Connection, _preReceiveEnvironment); + } + } + + public class TheTriggerDownloadMethod : IDisposable + { + private readonly IObservableGitHubClient _githubEnterprise; + private readonly IObservableEnterprisePreReceiveEnvironmentsClient _preReceiveEnvironmentsClient; + private readonly PreReceiveEnvironment _preReceiveEnvironment; + + public TheTriggerDownloadMethod() + { + _githubEnterprise = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient()); + _preReceiveEnvironmentsClient = _githubEnterprise.Enterprise.PreReceiveEnvironment; + + var newPreReceiveEnvironment = new NewPreReceiveEnvironment(Helper.MakeNameWithTimestamp("pre-receive"), "https://example.com/foo.zip"); + _preReceiveEnvironment = _preReceiveEnvironmentsClient.Create(newPreReceiveEnvironment).Wait(); + EnterpriseHelper.WaitForPreReceiveEnvironmentToComplete(_githubEnterprise.Connection, _preReceiveEnvironment); + } + + [GitHubEnterpriseTest] + public async Task CanTriggerDownload() + { + var downloadStatus = await _preReceiveEnvironmentsClient.DownloadStatus(_preReceiveEnvironment.Id); + + Assert.NotNull(downloadStatus); + } + + [GitHubEnterpriseTest] + public async Task CannotTriggerDownloadWhenNoEnvironmentExists() + { + await Assert.ThrowsAsync(async () => await _preReceiveEnvironmentsClient.DownloadStatus(-1)); + } + + public void Dispose() + { + EnterpriseHelper.DeletePreReceiveEnvironment(_githubEnterprise.Connection, _preReceiveEnvironment); + } + } +} diff --git a/Octokit.Tests/Clients/Enterprise/EnterprisePreReceiveEnvironmentsClientTests.cs b/Octokit.Tests/Clients/Enterprise/EnterprisePreReceiveEnvironmentsClientTests.cs new file mode 100644 index 00000000..c1ee944e --- /dev/null +++ b/Octokit.Tests/Clients/Enterprise/EnterprisePreReceiveEnvironmentsClientTests.cs @@ -0,0 +1,179 @@ +using System; +using System.Threading.Tasks; +using NSubstitute; +using Xunit; + +namespace Octokit.Tests.Clients +{ + public class EnterprisePreReceiveEnvironmentsClientTests + { + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new EnterprisePreReceiveEnvironmentsClient(null)); + } + } + + public class TheGetAllMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveEnvironmentsClient(connection); + + await client.GetAll(); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "admin/pre-receive-environments"), + null, + "application/vnd.github.eye-scream-preview+json", + Args.ApiOptions); + } + + [Fact] + public async Task RequestsCorrectUrlWithApiOptions() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveEnvironmentsClient(connection); + + var options = new ApiOptions + { + PageSize = 1, + PageCount = 1, + StartPage = 1 + }; + + await client.GetAll(options); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "admin/pre-receive-environments"), + null, + "application/vnd.github.eye-scream-preview+json", + options); + } + } + + public class TheGetMethod + { + [Fact] + public async Task RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveEnvironmentsClient(connection); + + await client.Get(1); + + connection.Received().Get(Arg.Is(u => u.ToString() == "admin/pre-receive-environments/1"), + null, + "application/vnd.github.eye-scream-preview+json"); + } + } + + public class TheCreateMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveEnvironmentsClient(connection); + var data = new NewPreReceiveEnvironment("name", "url"); + + await client.Create(data); + + connection.Received().Post(Arg.Is(u => u.ToString() == "admin/pre-receive-environments"), + data, + "application/vnd.github.eye-scream-preview+json"); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new EnterprisePreReceiveEnvironmentsClient(Substitute.For()); + Assert.Throws(() => new NewPreReceiveEnvironment(null, "url")); + Assert.Throws(() => new NewPreReceiveEnvironment("", "url")); + Assert.Throws(() => new NewPreReceiveEnvironment("name", null)); + Assert.Throws(() => new NewPreReceiveEnvironment("name", "")); + + await Assert.ThrowsAsync(() => client.Create(null)); + } + } + + public class TheEditMethod + { + [Fact] + public async Task RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveEnvironmentsClient(connection); + var data = new UpdatePreReceiveEnvironment + { + Name = "name", + ImageUrl = "url" + }; + + await client.Edit(1, data); + + connection.Received().Patch(Arg.Is(u => u.ToString() == "admin/pre-receive-environments/1"), + data, + "application/vnd.github.eye-scream-preview+json"); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new EnterprisePreReceiveEnvironmentsClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.Edit(1, null)); + } + } + + public class TheDeleteMethod + { + [Fact] + public async Task RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveEnvironmentsClient(connection); + + await client.Delete(1); + + connection.Received().Delete(Arg.Is(u => u.ToString() == "admin/pre-receive-environments/1"), + Arg.Any(), + "application/vnd.github.eye-scream-preview+json"); + } + } + + public class TheDownloadStatusMethod + { + [Fact] + public async Task RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveEnvironmentsClient(connection); + + await client.DownloadStatus(1); + + connection.Received().Get(Arg.Is(u => u.ToString() == "admin/pre-receive-environments/1/downloads/latest"), + null, + "application/vnd.github.eye-scream-preview+json"); + } + } + + public class TheTriggerDownloadMethod + { + [Fact] + public async Task RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveEnvironmentsClient(connection); + + await client.TriggerDownload(1); + + connection.Received().Post(Arg.Is(u => u.ToString() == "admin/pre-receive-environments/1/downloads"), + Arg.Any(), + "application/vnd.github.eye-scream-preview+json"); + } + } + } +} diff --git a/Octokit.Tests/Reactive/Enterprise/ObservableEnterprisePreReceiveEnvironmentsClientTests.cs b/Octokit.Tests/Reactive/Enterprise/ObservableEnterprisePreReceiveEnvironmentsClientTests.cs new file mode 100644 index 00000000..e6396def --- /dev/null +++ b/Octokit.Tests/Reactive/Enterprise/ObservableEnterprisePreReceiveEnvironmentsClientTests.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using NSubstitute; +using Octokit.Reactive; +using Xunit; + +namespace Octokit.Tests.Reactive +{ + public class ObservableEnterprisePreReceiveEnvironmentsClientTests + { + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new ObservableEnterprisePreReceiveEnvironmentsClient(null)); + } + } + + public class TheGetAllMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservableEnterprisePreReceiveEnvironmentsClient(gitHubClient); + + client.GetAll(); + + gitHubClient.Connection.Received(1).Get>( + new Uri("admin/pre-receive-environments", UriKind.Relative), + Args.EmptyDictionary, + "application/vnd.github.eye-scream-preview+json"); + } + + [Fact] + public void RequestsTheCorrectUrlWithApiOptions() + { + var gitHubClient = Substitute.For(); + var client = new ObservableEnterprisePreReceiveEnvironmentsClient(gitHubClient); + + var options = new ApiOptions + { + PageCount = 1, + PageSize = 1, + StartPage = 1 + }; + + client.GetAll(options); + + gitHubClient.Connection.Received(1).Get>( + new Uri("admin/pre-receive-environments", UriKind.Relative), + Arg.Is>(d => d.Count == 2), + "application/vnd.github.eye-scream-preview+json"); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservableEnterprisePreReceiveEnvironmentsClient(Substitute.For()); + + Assert.Throws(() => client.GetAll(null)); + } + } + + public class TheGetMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservableEnterprisePreReceiveEnvironmentsClient(gitHubClient); + + client.Get(1); + + gitHubClient.Enterprise.PreReceiveEnvironment.Received(1).Get(1); + } + } + + public class TheCreateMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservableEnterprisePreReceiveEnvironmentsClient(gitHubClient); + var data = new NewPreReceiveEnvironment("name", "url"); + + client.Create(data); + + gitHubClient.Enterprise.PreReceiveEnvironment.Received(1).Create(data); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservableEnterprisePreReceiveEnvironmentsClient(Substitute.For()); + + Assert.Throws(() => new NewPreReceiveEnvironment(null, "url")); + Assert.Throws(() => new NewPreReceiveEnvironment("", "url")); + Assert.Throws(() => new NewPreReceiveEnvironment("name", null)); + Assert.Throws(() => new NewPreReceiveEnvironment("name", "")); + + Assert.Throws(() => client.Create(null)); + } + } + + public class TheEditMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var gitHubClient = Substitute.For(); + var releasesClient = new ObservableEnterprisePreReceiveEnvironmentsClient(gitHubClient); + var data = new UpdatePreReceiveEnvironment + { + Name = "name", + ImageUrl = "url" + }; + + releasesClient.Edit(1, data); + + gitHubClient.Enterprise.PreReceiveEnvironment.Received(1).Edit(1, data); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservableEnterprisePreReceiveEnvironmentsClient(Substitute.For()); + + Assert.Throws(() => client.Edit(1, null)); + } + } + + public class TheDeleteMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservableEnterprisePreReceiveEnvironmentsClient(gitHubClient); + + client.Delete(1); + + gitHubClient.Enterprise.PreReceiveEnvironment.Received(1).Delete(1); + } + } + + public class TheDownloadStatusMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservableEnterprisePreReceiveEnvironmentsClient(gitHubClient); + + client.DownloadStatus(1); + + gitHubClient.Enterprise.PreReceiveEnvironment.Received(1).DownloadStatus(1); + } + } + + public class TheTriggerDownloadMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservableEnterprisePreReceiveEnvironmentsClient(gitHubClient); + + client.TriggerDownload(1); + + gitHubClient.Enterprise.PreReceiveEnvironment.Received(1).TriggerDownload(1); + } + } + } +} diff --git a/Octokit/Clients/Enterprise/EnterpriseClient.cs b/Octokit/Clients/Enterprise/EnterpriseClient.cs index aa5bb9d4..d5b6d30b 100644 --- a/Octokit/Clients/Enterprise/EnterpriseClient.cs +++ b/Octokit/Clients/Enterprise/EnterpriseClient.cs @@ -19,6 +19,7 @@ License = new EnterpriseLicenseClient(apiConnection); Organization = new EnterpriseOrganizationClient(apiConnection); SearchIndexing = new EnterpriseSearchIndexingClient(apiConnection); + PreReceiveEnvironment = new EnterprisePreReceiveEnvironmentsClient(apiConnection); } /// @@ -60,5 +61,13 @@ /// See the Enterprise Search Indexing API documentation for more information. /// public IEnterpriseSearchIndexingClient SearchIndexing { get; private set; } + + /// + /// A client for GitHub's Enterprise Pre-receive Environments API + /// + /// + /// See the Enterprise Pre-receive Environments API documentation for more information. + /// + public IEnterprisePreReceiveEnvironmentsClient PreReceiveEnvironment { get; private set; } } } diff --git a/Octokit/Clients/Enterprise/EnterprisePreReceiveEnvironmentsClient.cs b/Octokit/Clients/Enterprise/EnterprisePreReceiveEnvironmentsClient.cs new file mode 100644 index 00000000..39584ca8 --- /dev/null +++ b/Octokit/Clients/Enterprise/EnterprisePreReceiveEnvironmentsClient.cs @@ -0,0 +1,143 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + /// + /// A client for GitHub's Enterprise Pre-receive Environments API + /// + /// + /// See the Enterprise Pre-receive Environments API documentation for more information. + /// + public class EnterprisePreReceiveEnvironmentsClient : ApiClient, IEnterprisePreReceiveEnvironmentsClient + { + /// + /// Initializes a new instance of . + /// + /// An API connection + public EnterprisePreReceiveEnvironmentsClient(IApiConnection apiConnection) + : base(apiConnection) + { } + + /// + /// Gets all s. + /// + /// + /// See the API documentation for more information. + /// + /// Thrown when a general API error occurs. + public Task> GetAll() + { + return GetAll(ApiOptions.None); + } + + /// + /// Gets all s. + /// + /// + /// See the API documentation for more information. + /// + /// Options for changing the API response + /// Thrown when a general API error occurs. + public Task> GetAll(ApiOptions options) + { + var endpoint = ApiUrls.AdminPreReceiveEnvironments(); + return ApiConnection.GetAll(endpoint, null, AcceptHeaders.PreReceiveEnvironmentsPreview, options); + } + + /// + /// Gets a single . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public Task Get(long environmentId) + { + var endpoint = ApiUrls.AdminPreReceiveEnvironments(environmentId); + return ApiConnection.Get(endpoint, null, AcceptHeaders.PreReceiveEnvironmentsPreview); + } + + /// + /// Creates a new . + /// + /// + /// See the API documentation for more information. + /// + /// A description of the pre-receive environment to create + /// Thrown when a general API error occurs. + public Task Create(NewPreReceiveEnvironment newPreReceiveEnvironment) + { + Ensure.ArgumentNotNull(newPreReceiveEnvironment, nameof(newPreReceiveEnvironment)); + + var endpoint = ApiUrls.AdminPreReceiveEnvironments(); + return ApiConnection.Post(endpoint, newPreReceiveEnvironment, AcceptHeaders.PreReceiveEnvironmentsPreview); + } + + /// + /// Edits an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// A description of the pre-receive environment to edit + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public Task Edit(long environmentId, UpdatePreReceiveEnvironment updatePreReceiveEnvironment) + { + Ensure.ArgumentNotNull(updatePreReceiveEnvironment, nameof(updatePreReceiveEnvironment)); + + var endpoint = ApiUrls.AdminPreReceiveEnvironments(environmentId); + return ApiConnection.Patch(endpoint, updatePreReceiveEnvironment, AcceptHeaders.PreReceiveEnvironmentsPreview); + } + + /// + /// Deletes an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public Task Delete(long environmentId) + { + var endpoint = ApiUrls.AdminPreReceiveEnvironments(environmentId); + return ApiConnection.Delete(endpoint, new object(), AcceptHeaders.PreReceiveEnvironmentsPreview); + } + + /// + /// Gets the download status for an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public Task DownloadStatus(long environmentId) + { + var endpoint = ApiUrls.AdminPreReceiveEnvironmentDownloadStatus(environmentId); + return ApiConnection.Get(endpoint, null, AcceptHeaders.PreReceiveEnvironmentsPreview); + } + + /// + /// Triggers a new download of the 's tarball from the environment's . + /// When the download is finished, the newly downloaded tarball will overwrite the existing environment. + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public Task TriggerDownload(long environmentId) + { + var endpoint = ApiUrls.AdminPreReceiveEnvironmentDownload(environmentId); + return ApiConnection.Post(endpoint, new object(), AcceptHeaders.PreReceiveEnvironmentsPreview); + } + } +} diff --git a/Octokit/Clients/Enterprise/IEnterpriseClient.cs b/Octokit/Clients/Enterprise/IEnterpriseClient.cs index 28a5db22..8f3ace37 100644 --- a/Octokit/Clients/Enterprise/IEnterpriseClient.cs +++ b/Octokit/Clients/Enterprise/IEnterpriseClient.cs @@ -47,5 +47,13 @@ /// See the Enterprise Search Indexing API documentation for more information. /// IEnterpriseSearchIndexingClient SearchIndexing { get; } + + /// + /// A client for GitHub's Enterprise Pre-receive Environments API + /// + /// + /// See the Enterprise Pre-receive Environments API documentation for more information. + /// + IEnterprisePreReceiveEnvironmentsClient PreReceiveEnvironment { get; } } } diff --git a/Octokit/Clients/Enterprise/IEnterprisePreReceiveEnvironmentsClient.cs b/Octokit/Clients/Enterprise/IEnterprisePreReceiveEnvironmentsClient.cs new file mode 100644 index 00000000..c7e805a2 --- /dev/null +++ b/Octokit/Clients/Enterprise/IEnterprisePreReceiveEnvironmentsClient.cs @@ -0,0 +1,100 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + /// + /// A client for GitHub's Enterprise Pre-receive Environments API + /// + /// + /// See the Enterprise Pre-receive Environments API documentation for more information. + /// + public interface IEnterprisePreReceiveEnvironmentsClient + { + /// + /// Gets all s. + /// + /// + /// See the API documentation for more information. + /// + /// Thrown when a general API error occurs. + Task> GetAll(); + + /// + /// Gets all s. + /// + /// + /// See the API documentation for more information. + /// + /// Options for changing the API response + /// Thrown when a general API error occurs. + Task> GetAll(ApiOptions options); + + /// + /// Gets a single . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + Task Get(long environmentId); + + /// + /// Creates a new . + /// + /// + /// See the API documentation for more information. + /// + /// A description of the pre-receive environment to create + /// Thrown when a general API error occurs. + Task Create(NewPreReceiveEnvironment newPreReceiveEnvironment); + + /// + /// Edits an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// A description of the pre-receive environment to edit + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + Task Edit(long environmentId, UpdatePreReceiveEnvironment updatePreReceiveEnvironment); + + /// + /// Deletes an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + Task Delete(long environmentId); + + /// + /// Gets the download status for an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + Task DownloadStatus(long environmentId); + + /// + /// Triggers a new download of the 's tarball from the environment's . + /// When the download is finished, the newly downloaded tarball will overwrite the existing environment. + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive environment + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + Task TriggerDownload(long environmentId); + } +} diff --git a/Octokit/Helpers/AcceptHeaders.cs b/Octokit/Helpers/AcceptHeaders.cs index e8389ee7..b3701aca 100644 --- a/Octokit/Helpers/AcceptHeaders.cs +++ b/Octokit/Helpers/AcceptHeaders.cs @@ -57,6 +57,8 @@ namespace Octokit public const string GitHubAppsPreview = "application/vnd.github.machine-man-preview+json"; + public const string PreReceiveEnvironmentsPreview = "application/vnd.github.eye-scream-preview+json"; + /// /// Combines multiple preview headers. GitHub API supports Accept header with multiple /// values separated by comma. diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index f2f1d7f7..53198747 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -2495,6 +2495,42 @@ namespace Octokit return "admin/keys/{0}".FormatUri(keyId); } + /// + /// Creates the for pre-receive environments. + /// + /// + public static Uri AdminPreReceiveEnvironments() + { + return "admin/pre-receive-environments".FormatUri(); + } + + /// + /// Creates the for pre-receive environments. + /// + /// + public static Uri AdminPreReceiveEnvironments(long environmentId) + { + return "admin/pre-receive-environments/{0}".FormatUri(environmentId); + } + + /// + /// Creates the for pre-receive environment download status. + /// + /// + public static Uri AdminPreReceiveEnvironmentDownload(long environmentId) + { + return "admin/pre-receive-environments/{0}/downloads".FormatUri(environmentId); + } + + /// + /// Creates the for pre-receive environment download status. + /// + /// + public static Uri AdminPreReceiveEnvironmentDownloadStatus(long environmentId) + { + return "admin/pre-receive-environments/{0}/downloads/latest".FormatUri(environmentId); + } + /// /// Creates the relative for altering administration status of a user. /// diff --git a/Octokit/Models/Request/Enterprise/NewPreReceiveEnvironment.cs b/Octokit/Models/Request/Enterprise/NewPreReceiveEnvironment.cs new file mode 100644 index 00000000..c0456918 --- /dev/null +++ b/Octokit/Models/Request/Enterprise/NewPreReceiveEnvironment.cs @@ -0,0 +1,41 @@ +using System.Diagnostics; +using System.Globalization; + +namespace Octokit +{ + /// + /// Describes a new pre-receive environment. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class NewPreReceiveEnvironment + { + /// + /// Initializes a new instance of the class. + /// + /// The name of the environment as displayed in the UI. + /// URL to the tarball that will be downloaded and extracted. + public NewPreReceiveEnvironment(string name, string imageUrl) + { + Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); + Ensure.ArgumentNotNullOrEmptyString(imageUrl, nameof(imageUrl)); + + Name = name; + ImageUrl = imageUrl; + } + + /// + /// The name of the environment as displayed in the UI. + /// + public string Name { get; set; } + + /// + /// URL to the tarball that will be downloaded and extracted. + /// + public string ImageUrl { get; set; } + + internal string DebuggerDisplay + { + get { return string.Format(CultureInfo.InvariantCulture, "Name: {0} ImageUrl: {1}", Name, ImageUrl); } + } + } +} diff --git a/Octokit/Models/Request/Enterprise/UpdatePreReceiveEnvironment.cs b/Octokit/Models/Request/Enterprise/UpdatePreReceiveEnvironment.cs new file mode 100644 index 00000000..b3367d7d --- /dev/null +++ b/Octokit/Models/Request/Enterprise/UpdatePreReceiveEnvironment.cs @@ -0,0 +1,27 @@ +using System.Diagnostics; +using System.Globalization; + +namespace Octokit +{ + /// + /// Describes an update to an existing pre-receive environment. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class UpdatePreReceiveEnvironment + { + /// + /// The name of the environment as displayed in the UI. + /// + public string Name { get; set; } + + /// + /// URL to the tarball that will be downloaded and extracted. + /// + public string ImageUrl { get; set; } + + internal string DebuggerDisplay + { + get { return string.Format(CultureInfo.InvariantCulture, "Name: {0} ImageUrl: {1}", Name, ImageUrl); } + } + } +} diff --git a/Octokit/Models/Response/Enterprise/PreReceiveEnvironment.cs b/Octokit/Models/Response/Enterprise/PreReceiveEnvironment.cs new file mode 100644 index 00000000..cf2c2ce6 --- /dev/null +++ b/Octokit/Models/Response/Enterprise/PreReceiveEnvironment.cs @@ -0,0 +1,92 @@ +using System; +using System.Diagnostics; +using System.Globalization; + +namespace Octokit +{ + /// + /// Describes a pre-receive environment. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class PreReceiveEnvironment + { + public PreReceiveEnvironment() + { } + + public PreReceiveEnvironment(long id, string name, string url, string imageUrl, string htmlUrl, bool defaultEnvironment, DateTimeOffset? createdAt, int hooksCount, PreReceiveEnvironmentDownload download) + { + Id = id; + Name = name; + Url = url; + ImageUrl = imageUrl; + HtmlUrl = htmlUrl; + DefaultEnvironment = defaultEnvironment; + CreatedAt = createdAt; + HooksCount = hooksCount; + Download = download; + } + + /// + /// Identifier for the pre-receive environment. + /// + public long Id { get; protected set; } + + /// + /// The name of the environment as displayed in the UI. + /// + public string Name { get; protected set; } + + /// + /// URL to the pre-receive environment. + /// + public string Url { get; protected set; } + + /// + /// URL to the tarball that will be downloaded and extracted. + /// + public string ImageUrl { get; protected set; } + + /// + /// UI URL to the pre-receive environment. + /// + public string HtmlUrl { get; protected set; } + + /// + /// Whether this is the default environment that ships with GitHub Enterprise. + /// + public bool DefaultEnvironment { get; protected set; } + + /// + /// The time when the pre-receive environment was created. + /// + public DateTimeOffset? CreatedAt { get; protected set; } + + /// + /// The number of pre-receive hooks that use this environment. + /// + public int HooksCount { get; protected set; } + + /// + /// This environment's download status. + /// + public PreReceiveEnvironmentDownload Download { get; protected set; } + + /// + /// Prepares an for use when updating a pre-receive environment. + /// + /// + public UpdatePreReceiveEnvironment ToUpdate() + { + return new UpdatePreReceiveEnvironment + { + Name = Name, + ImageUrl = ImageUrl + }; + } + + internal string DebuggerDisplay + { + get { return string.Format(CultureInfo.InvariantCulture, "Id: {0} Name: {1} ImageUrl: {2}", Id, Name, ImageUrl); } + } + } +} diff --git a/Octokit/Models/Response/Enterprise/PreReceiveEnvironmentDownload.cs b/Octokit/Models/Response/Enterprise/PreReceiveEnvironmentDownload.cs new file mode 100644 index 00000000..05200a1f --- /dev/null +++ b/Octokit/Models/Response/Enterprise/PreReceiveEnvironmentDownload.cs @@ -0,0 +1,49 @@ +using System; +using System.Diagnostics; +using System.Globalization; + +namespace Octokit +{ + /// + /// Describes the current download state of a pre-receive environment image. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class PreReceiveEnvironmentDownload + { + public PreReceiveEnvironmentDownload() + { } + + public PreReceiveEnvironmentDownload(string url, PreReceiveEnvironmentDownloadState state, string message, DateTimeOffset? downloadedAt) + { + Url = url; + State = state; + Message = message; + DownloadedAt = downloadedAt; + } + + /// + /// URL to the download status for a pre-receive environment. + /// + public string Url { get; protected set; } + + /// + /// The state of the most recent download. + /// + public StringEnum State { get; protected set; } + + /// + /// On failure, this will have any error messages produced. + /// + public string Message { get; protected set; } + + /// + /// The time when the most recent download started. + /// + public DateTimeOffset? DownloadedAt { get; protected set; } + + internal string DebuggerDisplay + { + get { return string.Format(CultureInfo.InvariantCulture, "State: {0} Message: {1}", State, Message); } + } + } +} diff --git a/Octokit/Models/Response/Enterprise/PreReceiveEnvironmentDownloadState.cs b/Octokit/Models/Response/Enterprise/PreReceiveEnvironmentDownloadState.cs new file mode 100644 index 00000000..055a9a1a --- /dev/null +++ b/Octokit/Models/Response/Enterprise/PreReceiveEnvironmentDownloadState.cs @@ -0,0 +1,22 @@ +using Octokit.Internal; + +namespace Octokit +{ + /// + /// The state of the most recent download. + /// + public enum PreReceiveEnvironmentDownloadState + { + [Parameter(Value = "not_started")] + NotStarted, + + [Parameter(Value = "in_progress")] + InProgress, + + [Parameter(Value = "success")] + Success, + + [Parameter(Value = "failed")] + Failed + } +} \ No newline at end of file