Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Environments API - GetAll list only feature #2613

Merged
merged 5 commits into from
Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Octokit.Reactive/Clients/IObservableRepositoriesClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,18 @@ public interface IObservableRepositoriesClient
/// Client for GitHub's Repository Deployments API
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/deployment/">Collaborators API documentation</a> for more details
/// See the <a href="https://docs.github.com/en/rest/deployments/deployments">Deployments API documentation</a> for more details
/// </remarks>
IObservableDeploymentsClient Deployment { get; }

/// <summary>
/// Client for GitHub's Repository Envirinments API
/// </summary>
/// <remarks>
/// See the <a href="https://docs.github.com/en/rest/deployments/environments/">Envirinments API documentation</a> for more details
/// </remarks>
IObservableRepositoryDeployEnvironmentsClient Environment { get; }

/// <summary>
/// Client for GitHub's Repository Statistics API.
/// Note that the GitHub API uses caching on these endpoints,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using Octokit.Models.Response;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace Octokit.Reactive
{
public interface IObservableRepositoryDeployEnvironmentsClient
{
/// <summary>
/// Gets all the environments for the specified repository. Any user with pull access
/// to a repository can view deployments.
/// </summary>
/// <remarks>
/// https://docs.github.com/en/rest/deployments/environments#list-environments
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
IObservable<DeploymentEnvironmentsResponse> GetAll(string owner, string name);

/// <summary>
/// Gets all the environments for the specified repository. Any user with pull access
/// to a repository can view deployments.
/// </summary>
/// <remarks>
/// https://docs.github.com/en/rest/deployments/environments#list-environments
/// </remarks>
/// <param name="repositoryId">The Id of the repository</param>
IObservable<DeploymentEnvironmentsResponse> GetAll(long repositoryId);


/// <summary>
/// Gets all the environments for the specified repository. Any user with pull access
/// to a repository can view deployments.
/// </summary>
/// <remarks>
/// https://docs.github.com/en/rest/deployments/environments#list-environments
/// </remarks>
/// <param name="owner">The owner of the repository</param>
/// <param name="name">The name of the repository</param>
/// <param name="options">Paging options</param>
IObservable<DeploymentEnvironmentsResponse> GetAll(string owner, string name, ApiOptions options);


/// <summary>
/// Gets all the environments for the specified repository. Any user with pull access
/// to a repository can view deployments.
/// </summary>
/// <remarks>
/// https://docs.github.com/en/rest/deployments/environments#list-environments
/// </remarks>
/// <param name="repositoryId">Repository ID</param>
/// <param name="options">Paging options</param>
IObservable<DeploymentEnvironmentsResponse> GetAll(long repositoryId, ApiOptions options);
}
}
52 changes: 52 additions & 0 deletions Octokit.Reactive/Clients/ObservableEnvironmentsClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.Reactive.Threading.Tasks;
using Octokit.Models.Response;
using Octokit.Reactive.Internal;

namespace Octokit.Reactive.Clients
{
public class ObservableEnvironmentsClient : IObservableRepositoryDeployEnvironmentsClient
{
readonly IRepositoryDeployEnvironmentsClient _client;
readonly IConnection _connection;

public ObservableEnvironmentsClient(IGitHubClient client)
{
Ensure.ArgumentNotNull(client, nameof(client));

_client = client.Repository.Environment;
_connection = client.Connection;
}

public IObservable<DeploymentEnvironmentsResponse> GetAll(string owner, string name)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));

return GetAll(owner, name, ApiOptions.None);
}

public IObservable<DeploymentEnvironmentsResponse> GetAll(long repositoryId)
{
return GetAll(repositoryId, ApiOptions.None);
}

public IObservable<DeploymentEnvironmentsResponse> GetAll(string owner, string name, ApiOptions options)
{
Ensure.ArgumentNotNullOrEmptyString(owner, nameof(owner));
Ensure.ArgumentNotNullOrEmptyString(name, nameof(name));
Ensure.ArgumentNotNull(options, nameof(options));

return _connection.GetAndFlattenAllPages<DeploymentEnvironmentsResponse>(
ApiUrls.DeploymentEnvironments(owner, name), options);
}

public IObservable<DeploymentEnvironmentsResponse> GetAll(long repositoryId, ApiOptions options)
{
Ensure.ArgumentNotNull(options, nameof(options));

return _connection.GetAndFlattenAllPages<DeploymentEnvironmentsResponse>(
ApiUrls.DeploymentEnvironments(repositoryId), options);
}
}
}
12 changes: 11 additions & 1 deletion Octokit.Reactive/Clients/ObservableRepositoriesClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public ObservableRepositoriesClient(IGitHubClient client)
Forks = new ObservableRepositoryForksClient(client);
Collaborator = new ObservableRepoCollaboratorsClient(client);
Deployment = new ObservableDeploymentsClient(client);
Environment = new ObservableEnvironmentsClient(client);
Statistics = new ObservableStatisticsClient(client);
PullRequest = new ObservablePullRequestsClient(client);
Branch = new ObservableRepositoryBranchesClient(client);
Expand Down Expand Up @@ -347,10 +348,19 @@ public IObservable<Repository> GetAllForOrg(string organization, ApiOptions opti
/// Client for GitHub's Repository Deployments API
/// </summary>
/// <remarks>
/// See the <a href="http://developer.github.com/v3/repos/deployment/">Collaborators API documentation</a> for more details
/// See the <a href="https://docs.github.com/en/rest/deployments/deployments">Deployments API documentation</a> for more details
/// </remarks>
public IObservableDeploymentsClient Deployment { get; private set; }


/// <summary>
/// Client for GitHub's Repository Environments API
/// </summary>
/// <remarks>
/// See the <a href="https://docs.github.com/en/rest/deployments/environments#about-the-deployment-environments-api/">Environments API documentation</a> for more details
/// </remarks>
public IObservableRepositoryDeployEnvironmentsClient Environment { get; private set; }

/// <summary>
/// Client for GitHub's Repository Statistics API
/// Note that the GitHub API uses caching on these endpoints,
Expand Down
145 changes: 145 additions & 0 deletions Octokit.Tests/Clients/EnvironmentsClientTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using NSubstitute;
using Octokit;
using Octokit.Models.Response;
using Octokit.Tests;
using Xunit;


namespace Octokit.Tests.Clients
{
public class EnvironmentsClientTests
{
public class TheGetAllMethod
{
const string name = "name";
const string owner = "owner";
const long repositoryId = 1;

[Fact]
public async Task EnsuresNonNullArguments()
{
var client = new DeploymentEnvironmentsClient(Substitute.For<IApiConnection>());

await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAll(null, name));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAll(owner, null));
await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAll(owner, name, null));

await Assert.ThrowsAsync<ArgumentNullException>(() => client.GetAll(repositoryId, null));
}

[Fact]
public async Task EnsuresNonEmptyArguments()
{
var client = new DeploymentEnvironmentsClient(Substitute.For<IApiConnection>());

await Assert.ThrowsAsync<ArgumentException>(() => client.GetAll("", name));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetAll(owner, ""));
}

[Theory]
[InlineData(" ")]
[InlineData("\n")]
[InlineData("\t")]
[InlineData(" ")]
[InlineData("\n\r")]
public async Task EnsuresNonWhitespaceArguments(string whitespace)
{
var client = new DeploymentEnvironmentsClient(Substitute.For<IApiConnection>());

await Assert.ThrowsAsync<ArgumentException>(() => client.GetAll(whitespace, name));
await Assert.ThrowsAsync<ArgumentException>(() => client.GetAll(owner, whitespace));
}

[Fact]
public async Task RequestsCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentEnvironmentsClient(connection);
var expectedUrl = string.Format("repos/{0}/{1}/environments", owner, name);

var res = await client.GetAll(owner, name);

connection.Received()
.Get<DeploymentEnvironmentsResponse>(
Arg.Is<Uri>(u => u.ToString() == expectedUrl));
}

[Fact]
public async Task RequestsCorrectUrlWithRepositoryId()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentEnvironmentsClient(connection);
var expectedUrl = string.Format("repositories/{0}/environments", repositoryId);

await client.GetAll(repositoryId);

connection.Received()
.Get<DeploymentEnvironmentsResponse>(Arg.Is<Uri>(u => u.ToString() == expectedUrl));
}

[Fact]
public async Task RequestsCorrectUrlWithApiOptions()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentEnvironmentsClient(connection);
var expectedUrl = string.Format("repos/{0}/{1}/environments", owner, name);

var options = new ApiOptions
{
PageSize = 10,
StartPage = 1
};

await client.GetAll(owner, name, options);

connection.Received()
.Get<DeploymentEnvironmentsResponse>(Arg.Is<Uri>(u => u.ToString() == expectedUrl),
Arg.Is<IDictionary<string, string>>(u => u["per_page"] == "10" && u["page"] == "1"));
}

[Fact]
public async Task RequestsCorrectUrlWithRepositoryIdWithApiOptions()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentEnvironmentsClient(connection);
var expectedUrl = string.Format("repositories/{0}/environments", repositoryId);

var options = new ApiOptions
{
PageSize = 10,
StartPage = 1
};

await client.GetAll(repositoryId, options);

connection.Received()
.Get<DeploymentEnvironmentsResponse>(Arg.Is<Uri>(u => u.ToString() == expectedUrl),
Arg.Is<IDictionary<string, string>>(u => u["per_page"] == "10" && u["page"] == "1"));
}

[Fact]
public void RequestsCorrectUrlWithPreviewAcceptHeaders()
{
var connection = Substitute.For<IApiConnection>();
var client = new DeploymentEnvironmentsClient(connection);
var expectedUrl = string.Format("repos/{0}/{1}/environments", owner, name);

client.GetAll(owner, name);
connection.Received()
.Get<DeploymentEnvironmentsResponse>(Arg.Is<Uri>(u => u.ToString() == expectedUrl));
}
}

public class TheCtor
{
[Fact]
public void EnsuresNonNullArguments()
{
Assert.Throws<ArgumentNullException>(() => new DeploymentEnvironmentsClient(null));
}
}
}
}
Loading