diff --git a/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseClient.cs b/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseClient.cs index f3aa7fdcc3..ed7cf6467e 100644 --- a/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseClient.cs +++ b/Octokit.Reactive/Clients/Enterprise/IObservableEnterpriseClient.cs @@ -63,5 +63,13 @@ public interface IObservableEnterpriseClient /// See the Enterprise Pre-receive Environments API documentation for more information. /// IObservableEnterprisePreReceiveEnvironmentsClient PreReceiveEnvironment { get; } + + /// + /// A client for GitHub's Enterprise Pre-receive Hooks API + /// + /// + /// See the Enterprise Pre-receive Hooks API documentation for more information. + /// + IObservableEnterprisePreReceiveHooksClient PreReceiveHook { get; } } } diff --git a/Octokit.Reactive/Clients/Enterprise/IObservableEnterprisePreReceiveHooksClient.cs b/Octokit.Reactive/Clients/Enterprise/IObservableEnterprisePreReceiveHooksClient.cs new file mode 100644 index 0000000000..1cd389481f --- /dev/null +++ b/Octokit.Reactive/Clients/Enterprise/IObservableEnterprisePreReceiveHooksClient.cs @@ -0,0 +1,77 @@ +using System; +using System.Reactive; + +namespace Octokit.Reactive +{ + /// + /// A client for GitHub's Enterprise Pre-receive Hooks API + /// + /// + /// See the Enterprise Pre-receive Hooks API documentation for more information. + /// + public interface IObservableEnterprisePreReceiveHooksClient + { + /// + /// 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 hook + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + IObservable Get(long hookId); + + /// + /// Creates a new . + /// + /// + /// See the API documentation for more information. + /// + /// A description of the pre-receive hook to create + /// Thrown when a general API error occurs. + IObservable Create(NewPreReceiveHook newPreReceiveHook); + + /// + /// Edits an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive hook + /// A description of the pre-receive hook to edit + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + IObservable Edit(long hookId, UpdatePreReceiveHook updatePreReceiveHook); + + /// + /// Deletes an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive hook + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + IObservable Delete(long hookId); + } +} diff --git a/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseClient.cs b/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseClient.cs index e9d01ae29e..44ddd5f528 100644 --- a/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseClient.cs +++ b/Octokit.Reactive/Clients/Enterprise/ObservableEnterpriseClient.cs @@ -19,6 +19,7 @@ public ObservableEnterpriseClient(IGitHubClient client) Organization = new ObservableEnterpriseOrganizationClient(client); SearchIndexing = new ObservableEnterpriseSearchIndexingClient(client); PreReceiveEnvironment = new ObservableEnterprisePreReceiveEnvironmentsClient(client); + PreReceiveHook = new ObservableEnterprisePreReceiveHooksClient(client); } /// @@ -76,5 +77,13 @@ public ObservableEnterpriseClient(IGitHubClient client) /// See the Enterprise Pre-receive Environments API documentation for more information. /// public IObservableEnterprisePreReceiveEnvironmentsClient PreReceiveEnvironment { get; private set; } + + /// + /// A client for GitHub's Enterprise Pre-receive Hooks API + /// + /// + /// See the Enterprise Pre-receive Hooks API documentation for more information. + /// + public IObservableEnterprisePreReceiveHooksClient PreReceiveHook { get; private set; } } } diff --git a/Octokit.Reactive/Clients/Enterprise/ObservableEnterprisePreReceiveHooksClient.cs b/Octokit.Reactive/Clients/Enterprise/ObservableEnterprisePreReceiveHooksClient.cs new file mode 100644 index 0000000000..7320aaa067 --- /dev/null +++ b/Octokit.Reactive/Clients/Enterprise/ObservableEnterprisePreReceiveHooksClient.cs @@ -0,0 +1,114 @@ +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 Hooks API + /// + /// + /// See the Enterprise Pre-receive Hooks API documentation for more information. + /// + public class ObservableEnterprisePreReceiveHooksClient : IObservableEnterprisePreReceiveHooksClient + { + readonly IEnterprisePreReceiveHooksClient _client; + readonly IConnection _connection; + + public ObservableEnterprisePreReceiveHooksClient(IGitHubClient client) + { + Ensure.ArgumentNotNull(client, nameof(client)); + + _client = client.Enterprise.PreReceiveHook; + _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.AdminPreReceiveHooks(), null, AcceptHeaders.StableVersionJson, options); + } + + /// + /// Gets a single . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive hook + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public IObservable Get(long hookId) + { + return _client.Get(hookId).ToObservable(); + } + + /// + /// Creates a new . + /// + /// + /// See the API documentation for more information. + /// + /// A description of the pre-receive hook to create + /// Thrown when a general API error occurs. + public IObservable Create(NewPreReceiveHook newPreReceiveHook) + { + Ensure.ArgumentNotNull(newPreReceiveHook, nameof(newPreReceiveHook)); + + return _client.Create(newPreReceiveHook).ToObservable(); + } + + /// + /// Edits an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive hook + /// A description of the pre-receive hook to edit + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public IObservable Edit(long hookId, UpdatePreReceiveHook updatePreReceiveHook) + { + Ensure.ArgumentNotNull(updatePreReceiveHook, nameof(updatePreReceiveHook)); + + return _client.Edit(hookId, updatePreReceiveHook).ToObservable(); + } + + /// + /// Deletes an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive hook + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + public IObservable Delete(long hookId) + { + return _client.Delete(hookId).ToObservable(); + } + } +} diff --git a/Octokit.Tests.Integration/Clients/Enterprise/EnterprisePreReceiveHooksClientTests.cs b/Octokit.Tests.Integration/Clients/Enterprise/EnterprisePreReceiveHooksClientTests.cs new file mode 100644 index 0000000000..4f4583779f --- /dev/null +++ b/Octokit.Tests.Integration/Clients/Enterprise/EnterprisePreReceiveHooksClientTests.cs @@ -0,0 +1,357 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Octokit; +using Octokit.Tests.Integration; +using Xunit; + +public class EnterprisePreReceiveHooksClientTests +{ + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new EnterprisePreReceiveHooksClient(null)); + } + } + + public class TheGetAllMethod : IDisposable + { + private readonly IGitHubClient _githubEnterprise; + private readonly IEnterprisePreReceiveHooksClient _preReceiveHooksClient; + private readonly List _preReceiveHooks; + + public TheGetAllMethod() + { + _githubEnterprise = EnterpriseHelper.GetAuthenticatedClient(); + _preReceiveHooksClient = _githubEnterprise.Enterprise.PreReceiveHook; + + _preReceiveHooks = new List(); + for (var count = 0; count < 3; count++) + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1); + _preReceiveHooks.Add(_preReceiveHooksClient.Create(newPreReceiveHook).Result); + } + } + + [GitHubEnterpriseTest] + public async Task ReturnsPreReceiveHooks() + { + var preReceiveHooks = await _preReceiveHooksClient.GetAll(); + + Assert.NotEmpty(preReceiveHooks); + } + + [GitHubEnterpriseTest] + public async Task ReturnsCorrectCountOfPreReceiveHooksWithoutStart() + { + var options = new ApiOptions + { + PageSize = 1, + PageCount = 1 + }; + + var preReceiveHooks = await _preReceiveHooksClient.GetAll(options); + + Assert.Equal(1, preReceiveHooks.Count); + } + + [GitHubEnterpriseTest] + public async Task ReturnsCorrectCountOfPreReceiveHooksWithStart() + { + var options = new ApiOptions + { + PageSize = 1, + PageCount = 1, + StartPage = 2 + }; + + var preReceiveHooks = await _preReceiveHooksClient.GetAll(options); + + Assert.Equal(1, preReceiveHooks.Count); + } + + [GitHubEnterpriseTest] + public async Task ReturnsDistinctResultsBasedOnStartPage() + { + var startOptions = new ApiOptions + { + PageSize = 1, + PageCount = 1 + }; + + var firstPage = await _preReceiveHooksClient.GetAll(startOptions); + + var skipStartOptions = new ApiOptions + { + PageSize = 1, + PageCount = 1, + StartPage = 2 + }; + + var secondPage = await _preReceiveHooksClient.GetAll(skipStartOptions); + + Assert.NotEqual(firstPage[0].Id, secondPage[0].Id); + } + + public void Dispose() + { + foreach (var preReceiveHook in _preReceiveHooks) + { + EnterpriseHelper.DeletePreReceiveHook(_githubEnterprise.Connection, preReceiveHook); + } + } + } + + public class TheGetMethod : IDisposable + { + private readonly IGitHubClient _githubEnterprise; + private readonly IEnterprisePreReceiveHooksClient _preReceiveHooksClient; + private readonly NewPreReceiveHook _expectedPreReceiveHook; + private readonly PreReceiveHook _preReceiveHook; + + public TheGetMethod() + { + _githubEnterprise = EnterpriseHelper.GetAuthenticatedClient(); + _preReceiveHooksClient = _githubEnterprise.Enterprise.PreReceiveHook; + + _expectedPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1) + { + AllowDownstreamConfiguration = true, + Enforcement = PreReceiveHookEnforcement.Testing, + }; + _preReceiveHook = _preReceiveHooksClient.Create(_expectedPreReceiveHook).Result; + } + + [GitHubEnterpriseTest] + public async Task ReturnsName() + { + var preReceiveHook = await _preReceiveHooksClient.Get(_preReceiveHook.Id); + + Assert.NotNull(preReceiveHook); + Assert.Equal(_expectedPreReceiveHook.Name, preReceiveHook.Name); + } + + [GitHubEnterpriseTest] + public async Task ReturnsScript() + { + var preReceiveHook = await _preReceiveHooksClient.Get(_preReceiveHook.Id); + + Assert.NotNull(preReceiveHook); + Assert.Equal(_expectedPreReceiveHook.Script, preReceiveHook.Script); + } + + [GitHubEnterpriseTest] + public async Task ReturnsRepository() + { + var preReceiveHook = await _preReceiveHooksClient.Get(_preReceiveHook.Id); + + Assert.NotNull(preReceiveHook); + Assert.NotNull(preReceiveHook.ScriptRepository); + Assert.Equal(_expectedPreReceiveHook.ScriptRepository.FullName, preReceiveHook.ScriptRepository.FullName); + } + + [GitHubEnterpriseTest] + public async Task ReturnsEnvironment() + { + var preReceiveHook = await _preReceiveHooksClient.Get(_preReceiveHook.Id); + + Assert.NotNull(preReceiveHook); + Assert.NotNull(preReceiveHook.Environment); + Assert.Equal(_expectedPreReceiveHook.Environment.Id, preReceiveHook.Environment.Id); + } + + [GitHubEnterpriseTest] + public async Task ReturnsAllowDownstreamConfiguration() + { + var preReceiveHook = await _preReceiveHooksClient.Get(_preReceiveHook.Id); + + Assert.NotNull(preReceiveHook); + Assert.Equal(_expectedPreReceiveHook.AllowDownstreamConfiguration, preReceiveHook.AllowDownstreamConfiguration); + } + + [GitHubEnterpriseTest] + public async Task ReturnsEnforcement() + { + var preReceiveHook = await _preReceiveHooksClient.Get(_preReceiveHook.Id); + + Assert.NotNull(preReceiveHook); + Assert.Equal(_expectedPreReceiveHook.Enforcement.Value, preReceiveHook.Enforcement); + } + + [GitHubEnterpriseTest] + public async Task NoHookExists() + { + await Assert.ThrowsAsync(() => _preReceiveHooksClient.Get(-1)); + } + + public void Dispose() + { + EnterpriseHelper.DeletePreReceiveHook(_githubEnterprise.Connection, _preReceiveHook); + } + } + + public class TheCreateMethod + { + private readonly IGitHubClient _githubEnterprise; + private readonly IEnterprisePreReceiveHooksClient _preReceiveHooksClient; + + public TheCreateMethod() + { + _githubEnterprise = EnterpriseHelper.GetAuthenticatedClient(); + _preReceiveHooksClient = _githubEnterprise.Enterprise.PreReceiveHook; + } + + [GitHubEnterpriseTest] + public async Task CanCreatePreReceiveHook() + { + PreReceiveHook preReceiveHook = null; + try + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1); + preReceiveHook = await _preReceiveHooksClient.Create(newPreReceiveHook); + + Assert.NotNull(preReceiveHook); + Assert.Equal(newPreReceiveHook.Name, preReceiveHook.Name); + Assert.Equal(newPreReceiveHook.Script, preReceiveHook.Script); + Assert.Equal(newPreReceiveHook.ScriptRepository.FullName, preReceiveHook.ScriptRepository.FullName); + Assert.Equal(newPreReceiveHook.Environment.Id, preReceiveHook.Environment.Id); + } + finally + { + //Cleanup + EnterpriseHelper.DeletePreReceiveHook(_githubEnterprise.Connection, preReceiveHook); + } + } + + [GitHubEnterpriseTest] + public async Task CannotCreateWhenRepoDoesNotExist() + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "doesntExist/repo", Helper.MakeNameWithTimestamp("script"), 1); + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Create(newPreReceiveHook)); + } + + [GitHubEnterpriseTest] + public async Task CannotCreateWhenEnvironmentDoesNotExist() + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), -1); + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Create(newPreReceiveHook)); + } + + [GitHubEnterpriseTest] + public async Task CannotCreateWithSameName() + { + PreReceiveHook preReceiveHook = null; + try + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1); + preReceiveHook = await _preReceiveHooksClient.Create(newPreReceiveHook); + + newPreReceiveHook.Script = Helper.MakeNameWithTimestamp("script"); + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Create(newPreReceiveHook)); + } + finally + { + //Cleanup + EnterpriseHelper.DeletePreReceiveHook(_githubEnterprise.Connection, preReceiveHook); + } + } + + [GitHubEnterpriseTest] + public async Task CannotCreateWithSameScript() + { + PreReceiveHook preReceiveHook = null; + try + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1); + preReceiveHook = await _preReceiveHooksClient.Create(newPreReceiveHook); + + newPreReceiveHook.Name = Helper.MakeNameWithTimestamp("hook"); + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Create(newPreReceiveHook)); + } + finally + { + //Cleanup + EnterpriseHelper.DeletePreReceiveHook(_githubEnterprise.Connection, preReceiveHook); + } + } + } + + public class TheEditMethod : IDisposable + { + private readonly IGitHubClient _githubEnterprise; + private readonly IEnterprisePreReceiveHooksClient _preReceiveHooksClient; + private readonly PreReceiveHook _preReceiveHook; + + public TheEditMethod() + { + _githubEnterprise = EnterpriseHelper.GetAuthenticatedClient(); + _preReceiveHooksClient = _githubEnterprise.Enterprise.PreReceiveHook; + + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1); + _preReceiveHook = _preReceiveHooksClient.Create(newPreReceiveHook).Result; + } + + [GitHubEnterpriseTest] + public async Task CanChangeName() + { + var updatePreReceiveHook = new UpdatePreReceiveHook + { + Name = Helper.MakeNameWithTimestamp("hook") + }; + + var updatedPreReceiveHook = await _preReceiveHooksClient.Edit(_preReceiveHook.Id, updatePreReceiveHook); + + Assert.Equal(_preReceiveHook.Id, updatedPreReceiveHook.Id); + Assert.Equal(updatePreReceiveHook.Name, updatedPreReceiveHook.Name); + } + + [GitHubEnterpriseTest] + public async Task CanChangeScript() + { + var updatePreReceiveHook = new UpdatePreReceiveHook + { + Script = Helper.MakeNameWithTimestamp("script") + }; + + var updatedPreReceiveHook = await _preReceiveHooksClient.Edit(_preReceiveHook.Id, updatePreReceiveHook); + + Assert.Equal(_preReceiveHook.Id, updatedPreReceiveHook.Id); + Assert.Equal(updatePreReceiveHook.Script, updatedPreReceiveHook.Script); + } + + public void Dispose() + { + EnterpriseHelper.DeletePreReceiveHook(_githubEnterprise.Connection, _preReceiveHook); + } + } + + public class TheDeleteMethod + { + private readonly IEnterprisePreReceiveHooksClient _preReceiveHooksClient; + + public TheDeleteMethod() + { + var githubEnterprise = EnterpriseHelper.GetAuthenticatedClient(); + _preReceiveHooksClient = githubEnterprise.Enterprise.PreReceiveHook; + } + + [GitHubEnterpriseTest] + public async Task CanDelete() + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1); + var preReceiveHook = await _preReceiveHooksClient.Create(newPreReceiveHook); + + await _preReceiveHooksClient.Delete(preReceiveHook.Id); + + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Get(preReceiveHook.Id)); + } + + [GitHubEnterpriseTest] + public async Task CannotDeleteWhenHookDoesNotExist() + { + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Delete(-1)); + } + } +} diff --git a/Octokit.Tests.Integration/EnterpriseHelper.cs b/Octokit.Tests.Integration/EnterpriseHelper.cs index bd9f5cde1e..3d123730a4 100644 --- a/Octokit.Tests.Integration/EnterpriseHelper.cs +++ b/Octokit.Tests.Integration/EnterpriseHelper.cs @@ -161,6 +161,20 @@ public static void DeletePreReceiveEnvironment(IConnection connection, PreReceiv } } + public static void DeletePreReceiveHook(IConnection connection, PreReceiveHook preReceiveHook) + { + if (preReceiveHook != null) + { + try + { + var client = new GitHubClient(connection); + client.Enterprise.PreReceiveHook.Delete(preReceiveHook.Id).Wait(TimeSpan.FromSeconds(15)); + } + catch + { } + } + } + public static void SetMaintenanceMode(IConnection connection, bool enabled) { try diff --git a/Octokit.Tests.Integration/Reactive/Enterprise/ObservableEnterprisePreReceiveHooksClientTests.cs b/Octokit.Tests.Integration/Reactive/Enterprise/ObservableEnterprisePreReceiveHooksClientTests.cs new file mode 100644 index 0000000000..2ec9b074a8 --- /dev/null +++ b/Octokit.Tests.Integration/Reactive/Enterprise/ObservableEnterprisePreReceiveHooksClientTests.cs @@ -0,0 +1,359 @@ +using System; +using System.Collections.Generic; +using System.Reactive.Linq; +using System.Threading.Tasks; +using Octokit; +using Octokit.Reactive; +using Octokit.Tests.Integration; +using Xunit; + +public class ObservableEnterprisePreReceiveHooksClientTests +{ + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new EnterprisePreReceiveHooksClient(null)); + } + } + + public class TheGetAllMethod : IDisposable + { + private readonly IObservableGitHubClient _githubEnterprise; + private readonly IObservableEnterprisePreReceiveHooksClient _preReceiveHooksClient; + private readonly List _preReceiveHooks; + + public TheGetAllMethod() + { + _githubEnterprise = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient()); + _preReceiveHooksClient = _githubEnterprise.Enterprise.PreReceiveHook; + + _preReceiveHooks = new List(); + for (var count = 0; count < 3; count++) + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1); + _preReceiveHooks.Add(_preReceiveHooksClient.Create(newPreReceiveHook).Wait()); + } + } + + [GitHubEnterpriseTest] + public async Task ReturnsPreReceiveHooks() + { + var preReceiveHooks = await _preReceiveHooksClient.GetAll().ToList(); + + Assert.NotEmpty(preReceiveHooks); + } + + [GitHubEnterpriseTest] + public async Task ReturnsCorrectCountOfPreReceiveHooksWithoutStart() + { + var options = new ApiOptions + { + PageSize = 1, + PageCount = 1 + }; + + var preReceiveHooks = await _preReceiveHooksClient.GetAll(options).ToList(); + + Assert.Equal(1, preReceiveHooks.Count); + } + + [GitHubEnterpriseTest] + public async Task ReturnsCorrectCountOfPreReceiveHooksWithStart() + { + var options = new ApiOptions + { + PageSize = 1, + PageCount = 1, + StartPage = 2 + }; + + var preReceiveHooks = await _preReceiveHooksClient.GetAll(options).ToList(); + + Assert.Equal(1, preReceiveHooks.Count); + } + + [GitHubEnterpriseTest] + public async Task ReturnsDistinctResultsBasedOnStartPage() + { + var startOptions = new ApiOptions + { + PageSize = 1, + PageCount = 1 + }; + + var firstPage = await _preReceiveHooksClient.GetAll(startOptions).ToList(); + + var skipStartOptions = new ApiOptions + { + PageSize = 1, + PageCount = 1, + StartPage = 2 + }; + + var secondPage = await _preReceiveHooksClient.GetAll(skipStartOptions).ToList(); + + Assert.NotEqual(firstPage[0].Id, secondPage[0].Id); + } + + public void Dispose() + { + foreach (var preReceiveHook in _preReceiveHooks) + { + EnterpriseHelper.DeletePreReceiveHook(_githubEnterprise.Connection, preReceiveHook); + } + } + } + + public class TheGetMethod : IDisposable + { + private readonly IObservableGitHubClient _githubEnterprise; + private readonly IObservableEnterprisePreReceiveHooksClient _preReceiveHooksClient; + private readonly NewPreReceiveHook _expectedPreReceiveHook; + private readonly PreReceiveHook _preReceiveHook; + + public TheGetMethod() + { + _githubEnterprise = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient()); + _preReceiveHooksClient = _githubEnterprise.Enterprise.PreReceiveHook; + + _expectedPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1) + { + AllowDownstreamConfiguration = true, + Enforcement = PreReceiveHookEnforcement.Testing, + }; + _preReceiveHook = _preReceiveHooksClient.Create(_expectedPreReceiveHook).Wait(); + } + + [GitHubEnterpriseTest] + public async Task ReturnsName() + { + var preReceiveHook = await _preReceiveHooksClient.Get(_preReceiveHook.Id); + + Assert.NotNull(preReceiveHook); + Assert.Equal(_expectedPreReceiveHook.Name, preReceiveHook.Name); + } + + [GitHubEnterpriseTest] + public async Task ReturnsScript() + { + var preReceiveHook = await _preReceiveHooksClient.Get(_preReceiveHook.Id); + + Assert.NotNull(preReceiveHook); + Assert.Equal(_expectedPreReceiveHook.Script, preReceiveHook.Script); + } + + [GitHubEnterpriseTest] + public async Task ReturnsRepository() + { + var preReceiveHook = await _preReceiveHooksClient.Get(_preReceiveHook.Id); + + Assert.NotNull(preReceiveHook); + Assert.NotNull(preReceiveHook.ScriptRepository); + Assert.Equal(_expectedPreReceiveHook.ScriptRepository.FullName, preReceiveHook.ScriptRepository.FullName); + } + + [GitHubEnterpriseTest] + public async Task ReturnsEnvironment() + { + var preReceiveHook = await _preReceiveHooksClient.Get(_preReceiveHook.Id); + + Assert.NotNull(preReceiveHook); + Assert.NotNull(preReceiveHook.Environment); + Assert.Equal(_expectedPreReceiveHook.Environment.Id, preReceiveHook.Environment.Id); + } + + [GitHubEnterpriseTest] + public async Task ReturnsAllowDownstreamConfiguration() + { + var preReceiveHook = await _preReceiveHooksClient.Get(_preReceiveHook.Id); + + Assert.NotNull(preReceiveHook); + Assert.Equal(_expectedPreReceiveHook.AllowDownstreamConfiguration, preReceiveHook.AllowDownstreamConfiguration); + } + + [GitHubEnterpriseTest] + public async Task ReturnsEnforcement() + { + var preReceiveHook = await _preReceiveHooksClient.Get(_preReceiveHook.Id); + + Assert.NotNull(preReceiveHook); + Assert.Equal(_expectedPreReceiveHook.Enforcement.Value, preReceiveHook.Enforcement); + } + + [GitHubEnterpriseTest] + public async Task NoHookExists() + { + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Get(-1)); + } + + public void Dispose() + { + EnterpriseHelper.DeletePreReceiveHook(_githubEnterprise.Connection, _preReceiveHook); + } + } + + public class TheCreateMethod + { + private readonly IObservableGitHubClient _githubEnterprise; + private readonly IObservableEnterprisePreReceiveHooksClient _preReceiveHooksClient; + + public TheCreateMethod() + { + _githubEnterprise = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient()); + _preReceiveHooksClient = _githubEnterprise.Enterprise.PreReceiveHook; + } + + [GitHubEnterpriseTest] + public async Task CanCreatePreReceiveHook() + { + PreReceiveHook preReceiveHook = null; + try + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1); + preReceiveHook = await _preReceiveHooksClient.Create(newPreReceiveHook); + + Assert.NotNull(preReceiveHook); + Assert.Equal(newPreReceiveHook.Name, preReceiveHook.Name); + Assert.Equal(newPreReceiveHook.Script, preReceiveHook.Script); + Assert.Equal(newPreReceiveHook.ScriptRepository.FullName, preReceiveHook.ScriptRepository.FullName); + Assert.Equal(newPreReceiveHook.Environment.Id, preReceiveHook.Environment.Id); + } + finally + { + //Cleanup + EnterpriseHelper.DeletePreReceiveHook(_githubEnterprise.Connection, preReceiveHook); + } + } + + [GitHubEnterpriseTest] + public async Task CannotCreateWhenRepoDoesNotExist() + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "doesntExist/repo", Helper.MakeNameWithTimestamp("script"), 1); + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Create(newPreReceiveHook)); + } + + [GitHubEnterpriseTest] + public async Task CannotCreateWhenEnvironmentDoesNotExist() + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), -1); + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Create(newPreReceiveHook)); + } + + [GitHubEnterpriseTest] + public async Task CannotCreateWithSameName() + { + PreReceiveHook preReceiveHook = null; + try + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1); + preReceiveHook = await _preReceiveHooksClient.Create(newPreReceiveHook); + + newPreReceiveHook.Script = Helper.MakeNameWithTimestamp("script"); + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Create(newPreReceiveHook)); + } + finally + { + //Cleanup + EnterpriseHelper.DeletePreReceiveHook(_githubEnterprise.Connection, preReceiveHook); + } + } + + [GitHubEnterpriseTest] + public async Task CannotCreateWithSameScript() + { + PreReceiveHook preReceiveHook = null; + try + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1); + preReceiveHook = await _preReceiveHooksClient.Create(newPreReceiveHook); + + newPreReceiveHook.Name = Helper.MakeNameWithTimestamp("hook"); + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Create(newPreReceiveHook)); + } + finally + { + //Cleanup + EnterpriseHelper.DeletePreReceiveHook(_githubEnterprise.Connection, preReceiveHook); + } + } + } + + public class TheEditMethod : IDisposable + { + private readonly IObservableGitHubClient _githubEnterprise; + private readonly IObservableEnterprisePreReceiveHooksClient _preReceiveHooksClient; + private readonly PreReceiveHook _preReceiveHook; + + public TheEditMethod() + { + _githubEnterprise = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient()); + _preReceiveHooksClient = _githubEnterprise.Enterprise.PreReceiveHook; + + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1); + _preReceiveHook = _preReceiveHooksClient.Create(newPreReceiveHook).Wait(); + } + + [GitHubEnterpriseTest] + public async Task CanChangeName() + { + var updatePreReceiveHook = new UpdatePreReceiveHook + { + Name = Helper.MakeNameWithTimestamp("hook") + }; + + var updatedPreReceiveHook = await _preReceiveHooksClient.Edit(_preReceiveHook.Id, updatePreReceiveHook); + + Assert.Equal(_preReceiveHook.Id, updatedPreReceiveHook.Id); + Assert.Equal(updatePreReceiveHook.Name, updatedPreReceiveHook.Name); + } + + [GitHubEnterpriseTest] + public async Task CanChangeScript() + { + var updatePreReceiveHook = new UpdatePreReceiveHook + { + Script = Helper.MakeNameWithTimestamp("script") + }; + + var updatedPreReceiveHook = await _preReceiveHooksClient.Edit(_preReceiveHook.Id, updatePreReceiveHook); + + Assert.Equal(_preReceiveHook.Id, updatedPreReceiveHook.Id); + Assert.Equal(updatePreReceiveHook.Script, updatedPreReceiveHook.Script); + } + + public void Dispose() + { + EnterpriseHelper.DeletePreReceiveHook(_githubEnterprise.Connection, _preReceiveHook); + } + } + + public class TheDeleteMethod + { + private readonly IObservableEnterprisePreReceiveHooksClient _preReceiveHooksClient; + + public TheDeleteMethod() + { + var githubEnterprise = new ObservableGitHubClient(EnterpriseHelper.GetAuthenticatedClient()); + _preReceiveHooksClient = githubEnterprise.Enterprise.PreReceiveHook; + } + + [GitHubEnterpriseTest] + public async Task CanDelete() + { + var newPreReceiveHook = new NewPreReceiveHook(Helper.MakeNameWithTimestamp("hook"), "octokit/octokit.net", Helper.MakeNameWithTimestamp("script"), 1); + var preReceiveHook = await _preReceiveHooksClient.Create(newPreReceiveHook); + + await _preReceiveHooksClient.Delete(preReceiveHook.Id); + + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Get(preReceiveHook.Id)); + } + + [GitHubEnterpriseTest] + public async Task CannotDeleteWhenHookDoesNotExist() + { + await Assert.ThrowsAsync(async () => await _preReceiveHooksClient.Delete(-1)); + } + } +} diff --git a/Octokit.Tests/Clients/Enterprise/EnterprisePreReceiveHooksClientTests.cs b/Octokit.Tests/Clients/Enterprise/EnterprisePreReceiveHooksClientTests.cs new file mode 100644 index 0000000000..fac4f0804f --- /dev/null +++ b/Octokit.Tests/Clients/Enterprise/EnterprisePreReceiveHooksClientTests.cs @@ -0,0 +1,158 @@ +using System; +using System.Threading.Tasks; +using NSubstitute; +using Xunit; + +namespace Octokit.Tests.Clients +{ + public class EnterprisePreReceiveHooksClientTests + { + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new EnterprisePreReceiveHooksClient(null)); + } + } + + public class TheGetAllMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveHooksClient(connection); + + await client.GetAll(); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "admin/pre-receive-hooks"), + null, + "application/vnd.github.v3+json", + Args.ApiOptions); + } + + [Fact] + public async Task RequestsCorrectUrlWithApiOptions() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveHooksClient(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-hooks"), + null, + "application/vnd.github.v3+json", + options); + } + } + + public class TheGetMethod + { + [Fact] + public async Task RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveHooksClient(connection); + + await client.Get(1); + + connection.Received().Get(Arg.Is(u => u.ToString() == "admin/pre-receive-hooks/1"), + null, + "application/vnd.github.v3+json"); + } + } + + public class TheCreateMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveHooksClient(connection); + var data = new NewPreReceiveHook("name", "repo", "script", 1); + + await client.Create(data); + + connection.Received().Post(Arg.Is(u => u.ToString() == "admin/pre-receive-hooks"), + data, + "application/vnd.github.v3+json"); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new EnterprisePreReceiveHooksClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.Create(null)); + + Assert.Throws(() => new NewPreReceiveHook(null, "repo", "script", 1)); + Assert.Throws(() => new NewPreReceiveHook("", "repo", "script", 1)); + Assert.Throws(() => new NewPreReceiveHook("name", null, "script", 1)); + Assert.Throws(() => new NewPreReceiveHook("name", "", "script", 1)); + Assert.Throws(() => new NewPreReceiveHook("name", "repo", null, 1)); + Assert.Throws(() => new NewPreReceiveHook("name", "repo", "", 1)); + } + } + + public class TheEditMethod + { + [Fact] + public async Task RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveHooksClient(connection); + var data = new UpdatePreReceiveHook + { + Name = "name", + ScriptRepository = new RepositoryReference + { + FullName = "repo" + }, + Script = "script", + Environment = new PreReceiveEnvironmentReference + { + Id = 1 + } + }; + + await client.Edit(1, data); + + connection.Received().Patch(Arg.Is(u => u.ToString() == "admin/pre-receive-hooks/1"), + data, + "application/vnd.github.v3+json"); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new EnterprisePreReceiveHooksClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.Edit(1, null)); + } + } + + public class TheDeleteMethod + { + [Fact] + public async Task RequestsTheCorrectUrl() + { + var connection = Substitute.For(); + var client = new EnterprisePreReceiveHooksClient(connection); + + await client.Delete(1); + + connection.Received().Delete(Arg.Is(u => u.ToString() == "admin/pre-receive-hooks/1"), + Arg.Any(), + "application/vnd.github.v3+json"); + } + } + } +} diff --git a/Octokit.Tests/Reactive/Enterprise/ObservableEnterprisePreReceiveHooksClientTests.cs b/Octokit.Tests/Reactive/Enterprise/ObservableEnterprisePreReceiveHooksClientTests.cs new file mode 100644 index 0000000000..6158826762 --- /dev/null +++ b/Octokit.Tests/Reactive/Enterprise/ObservableEnterprisePreReceiveHooksClientTests.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using NSubstitute; +using Octokit.Reactive; +using Xunit; + +namespace Octokit.Tests.Reactive +{ + public class ObservableEnterprisePreReceiveHooksClientTests + { + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new ObservableEnterprisePreReceiveHooksClient(null)); + } + } + + public class TheGetAllMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservableEnterprisePreReceiveHooksClient(gitHubClient); + + client.GetAll(); + + gitHubClient.Connection.Received(1).Get>( + new Uri("admin/pre-receive-hooks", UriKind.Relative), + Args.EmptyDictionary, + "application/vnd.github.v3+json"); + } + + [Fact] + public void RequestsTheCorrectUrlWithApiOptions() + { + var gitHubClient = Substitute.For(); + var client = new ObservableEnterprisePreReceiveHooksClient(gitHubClient); + + var options = new ApiOptions + { + PageCount = 1, + PageSize = 1, + StartPage = 1 + }; + + client.GetAll(options); + + gitHubClient.Connection.Received(1).Get>( + new Uri("admin/pre-receive-hooks", UriKind.Relative), + Arg.Is>(d => d.Count == 2), + "application/vnd.github.v3+json"); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservableEnterprisePreReceiveHooksClient(Substitute.For()); + + Assert.Throws(() => client.GetAll(null)); + } + } + + public class TheGetMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservableEnterprisePreReceiveHooksClient(gitHubClient); + + client.Get(1); + + gitHubClient.Enterprise.PreReceiveHook.Received(1).Get(1); + } + } + + public class TheCreateMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservableEnterprisePreReceiveHooksClient(gitHubClient); + var data = new NewPreReceiveHook("name", "repo", "script", 1); + + client.Create(data); + + gitHubClient.Enterprise.PreReceiveHook.Received(1).Create(data); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservableEnterprisePreReceiveHooksClient(Substitute.For()); + + Assert.Throws(() => client.Create(null)); + + Assert.Throws(() => new NewPreReceiveHook(null, "repo", "script", 1)); + Assert.Throws(() => new NewPreReceiveHook("", "repo", "script", 1)); + Assert.Throws(() => new NewPreReceiveHook("name", null, "script", 1)); + Assert.Throws(() => new NewPreReceiveHook("name", "", "script", 1)); + Assert.Throws(() => new NewPreReceiveHook("name", "repo", null, 1)); + Assert.Throws(() => new NewPreReceiveHook("name", "repo", "", 1)); + } + } + + public class TheEditMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var gitHubClient = Substitute.For(); + var releasesClient = new ObservableEnterprisePreReceiveHooksClient(gitHubClient); + var data = new UpdatePreReceiveHook + { + Name = "name", + ScriptRepository = new RepositoryReference + { + FullName = "repo" + }, + Script = "script", + Environment = new PreReceiveEnvironmentReference + { + Id = 1 + } + }; + + releasesClient.Edit(1, data); + + gitHubClient.Enterprise.PreReceiveHook.Received(1).Edit(1, data); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservableEnterprisePreReceiveHooksClient(Substitute.For()); + + Assert.Throws(() => client.Edit(1, null)); + } + } + + public class TheDeleteMethod + { + [Fact] + public void RequestsTheCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservableEnterprisePreReceiveHooksClient(gitHubClient); + + client.Delete(1); + + gitHubClient.Enterprise.PreReceiveHook.Received(1).Delete(1); + } + } + } +} diff --git a/Octokit/Clients/Enterprise/EnterpriseClient.cs b/Octokit/Clients/Enterprise/EnterpriseClient.cs index d3d37fd42f..adfdaf1af3 100644 --- a/Octokit/Clients/Enterprise/EnterpriseClient.cs +++ b/Octokit/Clients/Enterprise/EnterpriseClient.cs @@ -21,6 +21,7 @@ public EnterpriseClient(IApiConnection apiConnection) : base(apiConnection) Organization = new EnterpriseOrganizationClient(apiConnection); SearchIndexing = new EnterpriseSearchIndexingClient(apiConnection); PreReceiveEnvironment = new EnterprisePreReceiveEnvironmentsClient(apiConnection); + PreReceiveHook = new EnterprisePreReceiveHooksClient(apiConnection); } /// @@ -78,5 +79,13 @@ public EnterpriseClient(IApiConnection apiConnection) : base(apiConnection) /// See the Enterprise Pre-receive Environments API documentation for more information. /// public IEnterprisePreReceiveEnvironmentsClient PreReceiveEnvironment { get; private set; } + + /// + /// A client for GitHub's Enterprise Pre-receive Hooks API + /// + /// + /// See the Enterprise Pre-receive Hooks API documentation for more information. + /// + public IEnterprisePreReceiveHooksClient PreReceiveHook { get; private set; } } } diff --git a/Octokit/Clients/Enterprise/EnterprisePreReceiveHooksClient.cs b/Octokit/Clients/Enterprise/EnterprisePreReceiveHooksClient.cs new file mode 100644 index 0000000000..6bde1e1952 --- /dev/null +++ b/Octokit/Clients/Enterprise/EnterprisePreReceiveHooksClient.cs @@ -0,0 +1,118 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + /// + /// A client for GitHub's Enterprise Pre-receive Hooks API + /// + /// + /// See the Enterprise Pre-receive Hooks API documentation for more information. + /// + public class EnterprisePreReceiveHooksClient : ApiClient, IEnterprisePreReceiveHooksClient + { + /// + /// Initializes a new instance of . + /// + /// An API connection + public EnterprisePreReceiveHooksClient(IApiConnection apiConnection) + : base(apiConnection) + { } + + /// + /// Gets all s. + /// + /// + /// See the API documentation for more information. + /// + /// Thrown when a general API error occurs. + [ManualRoute("GET", "/admin/pre-receive-hooks")] + 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. + [ManualRoute("GET", "/admin/pre-receive-hooks")] + public Task> GetAll(ApiOptions options) + { + var endpoint = ApiUrls.AdminPreReceiveHooks(); + return ApiConnection.GetAll(endpoint, null, AcceptHeaders.StableVersionJson, options); + } + + /// + /// Gets a single . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive hook + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + [ManualRoute("GET", "/admin/pre-receive-hooks/{pre_receive_hook_id}")] + public Task Get(long hookId) + { + var endpoint = ApiUrls.AdminPreReceiveHooks(hookId); + return ApiConnection.Get(endpoint, null, AcceptHeaders.StableVersionJson); + } + + /// + /// Creates a new . + /// + /// + /// See the API documentation for more information. + /// + /// A description of the pre-receive hook to create + /// Thrown when a general API error occurs. + [ManualRoute("POST", "/admin/pre-receive-hooks")] + public Task Create(NewPreReceiveHook newPreReceiveHook) + { + Ensure.ArgumentNotNull(newPreReceiveHook, nameof(newPreReceiveHook)); + + var endpoint = ApiUrls.AdminPreReceiveHooks(); + return ApiConnection.Post(endpoint, newPreReceiveHook, AcceptHeaders.StableVersionJson); + } + + /// + /// Edits an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive hook + /// A description of the pre-receive hook to edit + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + [ManualRoute("PATCH", "/admin/pre-receive-hooks/{pre_receive_hook_id}")] + public Task Edit(long hookId, UpdatePreReceiveHook updatePreReceiveHook) + { + Ensure.ArgumentNotNull(updatePreReceiveHook, nameof(updatePreReceiveHook)); + + var endpoint = ApiUrls.AdminPreReceiveHooks(hookId); + return ApiConnection.Patch(endpoint, updatePreReceiveHook, AcceptHeaders.StableVersionJson); + } + + /// + /// Deletes an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive hook + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + [ManualRoute("DELETE", "/admin/pre-receive-hooks/{pre_receive_hook_id}")] + public Task Delete(long hookId) + { + var endpoint = ApiUrls.AdminPreReceiveHooks(hookId); + return ApiConnection.Delete(endpoint, new object(), AcceptHeaders.StableVersionJson); + } + } +} diff --git a/Octokit/Clients/Enterprise/IEnterpriseClient.cs b/Octokit/Clients/Enterprise/IEnterpriseClient.cs index 8a7841d5e0..30b1502d69 100644 --- a/Octokit/Clients/Enterprise/IEnterpriseClient.cs +++ b/Octokit/Clients/Enterprise/IEnterpriseClient.cs @@ -63,5 +63,13 @@ public interface IEnterpriseClient /// See the Enterprise Pre-receive Environments API documentation for more information. /// IEnterprisePreReceiveEnvironmentsClient PreReceiveEnvironment { get; } + + /// + /// A client for GitHub's Enterprise Pre-receive Hooks API + /// + /// + /// See the Enterprise Pre-receive Hooks API documentation for more information. + /// + IEnterprisePreReceiveHooksClient PreReceiveHook { get; } } } diff --git a/Octokit/Clients/Enterprise/IEnterprisePreReceiveHooksClient.cs b/Octokit/Clients/Enterprise/IEnterprisePreReceiveHooksClient.cs new file mode 100644 index 0000000000..eb1e0e09a2 --- /dev/null +++ b/Octokit/Clients/Enterprise/IEnterprisePreReceiveHooksClient.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + /// + /// A client for GitHub's Enterprise Pre-receive Hooks API + /// + /// + /// See the Enterprise Pre-receive Hooks API documentation for more information. + /// + public interface IEnterprisePreReceiveHooksClient + { + /// + /// 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 hook + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + Task Get(long hookId); + + /// + /// Creates a new . + /// + /// + /// See the API documentation for more information. + /// + /// A description of the pre-receive hook to create + /// Thrown when a general API error occurs. + Task Create(NewPreReceiveHook newPreReceiveHook); + + /// + /// Edits an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive hook + /// A description of the pre-receive hook to edit + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + Task Edit(long hookId, UpdatePreReceiveHook updatePreReceiveHook); + + /// + /// Deletes an existing . + /// + /// + /// See the API documentation for more information. + /// + /// The id of the pre-receive hook + /// Thrown when the specified does not exist. + /// Thrown when a general API error occurs. + Task Delete(long hookId); + } +} \ No newline at end of file diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index 74f0ff3f9c..c87c6783b6 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -2695,6 +2695,24 @@ public static Uri AdminPreReceiveEnvironmentDownloadStatus(long environmentId) return "admin/pre-receive-environments/{0}/downloads/latest".FormatUri(environmentId); } + /// + /// Creates the for pre-receive hooks. + /// + /// + public static Uri AdminPreReceiveHooks() + { + return "admin/pre-receive-hooks".FormatUri(); + } + + /// + /// Creates the for pre-receive hooks. + /// + /// + public static Uri AdminPreReceiveHooks(long hookId) + { + return "admin/pre-receive-hooks/{0}".FormatUri(hookId); + } + /// /// Creates the relative for altering administration status of a user. /// diff --git a/Octokit/Models/Request/Enterprise/NewPreReceiveHook.cs b/Octokit/Models/Request/Enterprise/NewPreReceiveHook.cs new file mode 100644 index 0000000000..2a5a4c442c --- /dev/null +++ b/Octokit/Models/Request/Enterprise/NewPreReceiveHook.cs @@ -0,0 +1,98 @@ +using System.Diagnostics; +using System.Globalization; + +namespace Octokit +{ + /// + /// Describes a new pre-receive hook. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class NewPreReceiveHook + { + /// + /// Initializes a new instance of the class. + /// + /// The name of the hook. + /// The script that the hook runs. + /// The repository where the script is kept. + /// The pre-receive environment where the script is executed. + public NewPreReceiveHook(string name, Repository scriptRepository, string script, PreReceiveEnvironment environment) + { + Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); + Ensure.ArgumentNotNull(scriptRepository, nameof(scriptRepository)); + Ensure.ArgumentNotNullOrEmptyString(script, nameof(script)); + Ensure.ArgumentNotNull(environment, nameof(environment)); + + Name = name; + ScriptRepository = new RepositoryReference + { + FullName = scriptRepository.FullName + }; + Script = script; + Environment = new PreReceiveEnvironmentReference + { + Id = environment.Id + }; + } + + /// + /// Initializes a new instance of the class. + /// + /// The name of the hook. + /// The script that the hook runs. + /// The of a repository where the script is kept. + /// The of a pre-receive environment where the script is executed. + public NewPreReceiveHook(string name, string scriptRepositoryFullName, string script, long environmentId) + { + Ensure.ArgumentNotNullOrEmptyString(name, nameof(name)); + Ensure.ArgumentNotNullOrEmptyString(script, nameof(script)); + Ensure.ArgumentNotNullOrEmptyString(scriptRepositoryFullName, nameof(scriptRepositoryFullName)); + + Name = name; + ScriptRepository = new RepositoryReference + { + FullName = scriptRepositoryFullName + }; + Script = script; + Environment = new PreReceiveEnvironmentReference + { + Id = environmentId + }; + } + + /// + /// The name of the hook. + /// + public string Name { get; set; } + + /// + /// The script that the hook runs. + /// + public string Script { get; set; } + + /// + /// The script that the hook runs. + /// + public RepositoryReference ScriptRepository { get; set; } + + /// + /// The script that the hook runs. + /// + public PreReceiveEnvironmentReference Environment { get; set; } + + /// + /// The state of enforcement for this hook. default: + /// + public PreReceiveHookEnforcement? Enforcement { get; set; } + + /// + /// Whether enforcement can be overridden at the org or repo level. default: false. + /// + public bool? AllowDownstreamConfiguration { get; set; } + + internal string DebuggerDisplay + { + get { return string.Format(CultureInfo.InvariantCulture, "Name: {0} Repo: {1} Script: {2}", Name, ScriptRepository.FullName, Script); } + } + } +} diff --git a/Octokit/Models/Request/Enterprise/PreReceiveEnvironmentReference.cs b/Octokit/Models/Request/Enterprise/PreReceiveEnvironmentReference.cs new file mode 100644 index 0000000000..be55542df7 --- /dev/null +++ b/Octokit/Models/Request/Enterprise/PreReceiveEnvironmentReference.cs @@ -0,0 +1,22 @@ +using System.Diagnostics; +using System.Globalization; + +namespace Octokit +{ + /// + /// A reference to a pre-receive environment. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class PreReceiveEnvironmentReference + { + /// + /// The identifier for the pre-receive environment. + /// + public long Id { get; set; } + + internal string DebuggerDisplay + { + get { return string.Format(CultureInfo.InvariantCulture, "Id: {0}", Id); } + } + } +} \ No newline at end of file diff --git a/Octokit/Models/Request/Enterprise/RepositoryReference.cs b/Octokit/Models/Request/Enterprise/RepositoryReference.cs new file mode 100644 index 0000000000..65490a7f69 --- /dev/null +++ b/Octokit/Models/Request/Enterprise/RepositoryReference.cs @@ -0,0 +1,22 @@ +using System.Diagnostics; +using System.Globalization; + +namespace Octokit +{ + /// + /// A Reference to a repository. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class RepositoryReference + { + /// + /// The full name for the repository. + /// + public string FullName { get; set; } + + internal string DebuggerDisplay + { + get { return string.Format(CultureInfo.InvariantCulture, "FullName: {0}", FullName); } + } + } +} \ No newline at end of file diff --git a/Octokit/Models/Request/Enterprise/UpdatePreReceiveHook.cs b/Octokit/Models/Request/Enterprise/UpdatePreReceiveHook.cs new file mode 100644 index 0000000000..69321558ee --- /dev/null +++ b/Octokit/Models/Request/Enterprise/UpdatePreReceiveHook.cs @@ -0,0 +1,47 @@ +using System.Diagnostics; +using System.Globalization; + +namespace Octokit +{ + /// + /// Describes a new pre-receive hook. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class UpdatePreReceiveHook + { + /// + /// The name of the hook. + /// + public string Name { get; set; } + + /// + /// The script that the hook runs. + /// + public string Script { get; set; } + + /// + /// The script that the hook runs. + /// + public RepositoryReference ScriptRepository { get; set; } + + /// + /// The script that the hook runs. + /// + public PreReceiveEnvironmentReference Environment { get; set; } + + /// + /// The state of enforcement for this hook. Defaults is + /// + public PreReceiveHookEnforcement? Enforcement { get; set; } + + /// + /// Whether enforcement can be overridden at the org or repo level. Default is false. + /// + public bool? AllowDownstreamConfiguration { get; set; } + + internal string DebuggerDisplay + { + get { return string.Format(CultureInfo.InvariantCulture, "Name: {0} Script: {1}", Name, Script); } + } + } +} diff --git a/Octokit/Models/Response/Enterprise/PreReceiveHook.cs b/Octokit/Models/Response/Enterprise/PreReceiveHook.cs new file mode 100644 index 0000000000..af9d5c7c51 --- /dev/null +++ b/Octokit/Models/Response/Enterprise/PreReceiveHook.cs @@ -0,0 +1,85 @@ +using System.Diagnostics; +using System.Globalization; + +namespace Octokit +{ + /// + /// Describes a pre-receive hook. + /// + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class PreReceiveHook + { + public PreReceiveHook() + { } + + public PreReceiveHook(int id, string name, StringEnum enforcement, string script, Repository scriptRepository, PreReceiveEnvironment environment, bool allowDownstreamConfiguration) + { + Id = id; + Name = name; + Enforcement = enforcement; + Script = script; + ScriptRepository = scriptRepository; + Environment = environment; + AllowDownstreamConfiguration = allowDownstreamConfiguration; + } + + /// + /// The identifier for the pre-receive hook. + /// + public int Id { get; protected set; } + + /// + /// The name of the hook. + /// + public string Name { get; protected set; } + + /// + /// The state of enforcement for this hook. + /// + public StringEnum Enforcement { get; protected set; } + + /// + /// The script that the hook runs. + /// + public string Script { get; protected set; } + + /// + /// The GitHub repository where the script is kept. + /// + public Repository ScriptRepository { get; protected set; } + + /// + /// The pre-receive environment where the script is executed. + /// + public PreReceiveEnvironment Environment { get; protected set; } + + /// + /// Whether enforcement can be overridden at the org or repo level. + /// + public bool AllowDownstreamConfiguration { get; protected set; } + + public UpdatePreReceiveHook ToUpdate() + { + return new UpdatePreReceiveHook + { + Name = Name, + Enforcement = Enforcement.Value, + Script = Script, + ScriptRepository = new RepositoryReference + { + FullName = ScriptRepository.FullName + }, + Environment = new PreReceiveEnvironmentReference + { + Id = Environment.Id + }, + AllowDownstreamConfiguration = AllowDownstreamConfiguration + }; + } + + internal string DebuggerDisplay + { + get { return string.Format(CultureInfo.InvariantCulture, "Id: {0} Name: {1} Script: {2}", Id, Name, Script); } + } + } +} diff --git a/Octokit/Models/Response/Enterprise/PreReceiveHookEnforcement.cs b/Octokit/Models/Response/Enterprise/PreReceiveHookEnforcement.cs new file mode 100644 index 0000000000..0734bd1a9f --- /dev/null +++ b/Octokit/Models/Response/Enterprise/PreReceiveHookEnforcement.cs @@ -0,0 +1,28 @@ +using Octokit.Internal; + +namespace Octokit +{ + /// + /// The state of enforcement for a hook. + /// + public enum PreReceiveHookEnforcement + { + /// + /// Indicates the pre-receive hook will not run. + /// + [Parameter(Value = "disabled")] + Disabled, + + /// + /// Indicates it will run and reject any pushes that result in a non-zero status. + /// + [Parameter(Value = "enabled")] + Enabled, + + /// + /// Means the script will run but will not cause any pushes to be rejected. + /// + [Parameter(Value = "testing")] + Testing + } +} \ No newline at end of file