diff --git a/Octokit.Reactive/Clients/IObservablePackageVersionsClient.cs b/Octokit.Reactive/Clients/IObservablePackageVersionsClient.cs new file mode 100644 index 00000000..5d2f0045 --- /dev/null +++ b/Octokit.Reactive/Clients/IObservablePackageVersionsClient.cs @@ -0,0 +1,152 @@ +using System; +using System.Reactive; + +namespace Octokit.Reactive +{ + public interface IObservablePackageVersionsClient + { + /// + /// List all versions of a package. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Optional: Return packages with a state. Defaults to Active + /// Optional: Paging options + IObservable GetAllForOrg(string org, PackageType packageType, string packageName, PackageVersionState state = PackageVersionState.Active, ApiOptions options = null); + + /// + /// Get a specific version of a package. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + + IObservable GetForOrg(string org, PackageType packageType, string packageName, int packageVersionId); + + /// + /// Deletes a specific package version in an organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + IObservable DeleteForOrg(string org, PackageType packageType, string packageName, int packageVersionId); + + /// + /// Restores a specific package version in an organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + IObservable RestoreForOrg(string org, PackageType packageType, string packageName, int packageVersionId); + + /// + /// Returns all package versions for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Optional: Return packages with a state. Defaults to Active + /// Optional: Paging options + IObservable GetAllForActiveUser(PackageType packageType, string packageName, PackageVersionState state = PackageVersionState.Active, ApiOptions options = null); + + /// + /// Gets a specific package version for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + IObservable GetForActiveUser(PackageType packageType, string packageName, int packageVersionId); + + /// + /// Deletes a specific package version for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + IObservable DeleteForActiveUser(PackageType packageType, string packageName, int packageVersionId); + + /// + /// Restores a package version owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + IObservable RestoreForActiveUser(PackageType packageType, string packageName, int packageVersionId); + + /// + /// Returns all package versions for a public package owned by a specified user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Optional: Return packages with a state. Defaults to Active + /// Optional: Paging options + IObservable GetAllForUser(string username, PackageType packageType, string packageName, PackageVersionState state = PackageVersionState.Active, ApiOptions options = null); + + /// + /// Gets a specific package version for a public package owned by a specified user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + IObservable GetForUser(string username, PackageType packageType, string packageName, int packageVersionId); + + /// + /// Deletes a specific package version for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + IObservable DeleteForUser(string username, PackageType packageType, string packageName, int packageVersionId); + + /// + /// Restores a specific package version for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + IObservable RestoreForUser(string username, PackageType packageType, string packageName, int packageVersionId); + } +} \ No newline at end of file diff --git a/Octokit.Reactive/Clients/IObservablePackagesClient.cs b/Octokit.Reactive/Clients/IObservablePackagesClient.cs new file mode 100644 index 00000000..6814cad8 --- /dev/null +++ b/Octokit.Reactive/Clients/IObservablePackagesClient.cs @@ -0,0 +1,138 @@ +using System; +using System.Reactive; + +namespace Octokit.Reactive +{ + public interface IObservablePackagesClient + { + IObservablePackageVersionsClient PackageVersions { get; } + + /// + /// List all packages for an organisations, readable by the current user + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Optional: The visibility of the package + IObservable GetAllForOrg(string org, PackageType packageType, PackageVisibility? packageVisibility = null); + + /// + /// Get a specific package for an Organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + IObservable GetForOrg(string org, PackageType packageType, string packageName); + + /// + /// Delete a specific package for an Organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + IObservable DeleteForOrg(string org, PackageType packageType, string packageName); + + /// + /// Restore a specific package for an Organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + IObservable RestoreForOrg(string org, PackageType packageType, string packageName); + + /// + /// Lists packages owned by the authenticated user within the user's namespace + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Optional: The visibility of the package + IObservable GetAllForActiveUser(PackageType packageType, PackageVisibility? packageVisibility = null); + + /// + /// Gets a specific package for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + IObservable GetForActiveUser(PackageType packageType, string packageName); + + /// + /// Deletes a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + IObservable DeleteForActiveUser(PackageType packageType, string packageName); + + /// + /// Restores a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + IObservable RestoreForActiveUser(PackageType packageType, string packageName); + + /// + /// Lists packages owned by the authenticated user within the user's namespace + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Optional: The visibility of the package + IObservable GetAllForUser(string username, PackageType packageType, PackageVisibility? packageVisibility = null); + + /// + /// Gets a specific package metadata for a public package owned by a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + IObservable GetForUser(string username, PackageType packageType, string packageName); + + /// + /// Deletes an entire package for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + IObservable DeleteForUser(string username, PackageType packageType, string packageName); + + /// + /// Restores an entire package for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + IObservable RestoreForUser(string username, PackageType packageType, string packageName); + } +} \ No newline at end of file diff --git a/Octokit.Reactive/Clients/ObservablePackageVersionsClient.cs b/Octokit.Reactive/Clients/ObservablePackageVersionsClient.cs new file mode 100644 index 00000000..f6ad28d7 --- /dev/null +++ b/Octokit.Reactive/Clients/ObservablePackageVersionsClient.cs @@ -0,0 +1,253 @@ +using Octokit.Reactive.Internal; +using System; +using System.Reactive; +using System.Reactive.Threading.Tasks; + +namespace Octokit.Reactive +{ + public class ObservablePackageVersionsClient : IObservablePackageVersionsClient + { + readonly IPackageVersionsClient _client; + readonly IConnection _connection; + + public ObservablePackageVersionsClient(IGitHubClient client) + { + Ensure.ArgumentNotNull(client, nameof(client)); + + _client = client.Packages.PackageVersions; + _connection = client.Connection; + } + + /// + /// List all versions of a package. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Optional: Return packages with a state. Defaults to Active + /// Optional: Paging options + public IObservable GetAllForOrg(string org, PackageType packageType, string packageName, PackageVersionState state = PackageVersionState.Active, ApiOptions options = null) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.ApiOptionsNotNull(ref options); + + var route = ApiUrls.PackageVersionsOrg(org, packageType, packageName); + var parameters = ParameterBuilder.AddParameter("state", state); + + return _connection.GetAndFlattenAllPages(route, parameters); + } + + /// + /// Get a specific version of a package. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + public IObservable GetForOrg(string org, PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + return _client.GetForOrg(org, packageType, packageName, packageVersionId).ToObservable(); + } + + /// + /// Deletes a specific package version in an organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + public IObservable DeleteForOrg(string org, PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + return _client.DeleteForOrg(org, packageType, packageName, packageVersionId).ToObservable(); + } + + /// + /// Restores a specific package version in an organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + public IObservable RestoreForOrg(string org, PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + return _client.RestoreForOrg(org, packageType, packageName, packageVersionId).ToObservable(); + } + + /// + /// Returns all package versions for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Optional: Return packages with a state. Defaults to Active + /// Optional: Paging options + public IObservable GetAllForActiveUser(PackageType packageType, string packageName, PackageVersionState state = PackageVersionState.Active, ApiOptions options = null) + { + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.ApiOptionsNotNull(ref options); + + var route = ApiUrls.PackageVersionsActiveUser(packageType, packageName); + var parameters = ParameterBuilder.AddParameter("state", state); + + return _connection.GetAndFlattenAllPages(route, parameters); + } + + /// + /// Gets a specific package version for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + public IObservable GetForActiveUser(PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + return _client.GetForActiveUser(packageType, packageName, packageVersionId).ToObservable(); + } + + /// + /// Deletes a specific package version for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + public IObservable DeleteForActiveUser(PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + return _client.DeleteForActiveUser(packageType, packageName, packageVersionId).ToObservable(); + } + + /// + /// Restores a package version owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + public IObservable RestoreForActiveUser(PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + return _client.RestoreForActiveUser(packageType, packageName, packageVersionId).ToObservable(); + } + + /// + /// Returns all package versions for a public package owned by a specified user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Optional: Return packages with a state. Defaults to Active + /// Optional: Paging options + public IObservable GetAllForUser(string username, PackageType packageType, string packageName, PackageVersionState state = PackageVersionState.Active, ApiOptions options = null) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.ApiOptionsNotNull(ref options); + + var route = ApiUrls.PackageVersionsUser(username, packageType, packageName); + var parameters = ParameterBuilder.AddParameter("state", state); + + return _connection.GetAndFlattenAllPages(route, parameters); + } + + /// + /// Gets a specific package version for a public package owned by a specified user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + public IObservable GetForUser(string username, PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + return _client.GetForUser(username, packageType, packageName, packageVersionId).ToObservable(); + } + + /// + /// Deletes a specific package version for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + public IObservable DeleteForUser(string username, PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + return _client.DeleteForUser(username, packageType, packageName, packageVersionId).ToObservable(); + } + + /// + /// Restores a specific package version for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + public IObservable RestoreForUser(string username, PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + return _client.RestoreForUser(username, packageType, packageName, packageVersionId).ToObservable(); + } + } +} \ No newline at end of file diff --git a/Octokit.Reactive/Clients/ObservablePackagesClient.cs b/Octokit.Reactive/Clients/ObservablePackagesClient.cs new file mode 100644 index 00000000..662efb55 --- /dev/null +++ b/Octokit.Reactive/Clients/ObservablePackagesClient.cs @@ -0,0 +1,235 @@ +using Octokit.Reactive.Internal; +using System; +using System.Reactive; +using System.Reactive.Threading.Tasks; + +namespace Octokit.Reactive +{ + public class ObservablePackagesClient : IObservablePackagesClient + { + readonly IPackagesClient _client; + readonly IConnection _connection; + + public ObservablePackagesClient(IGitHubClient client) + { + Ensure.ArgumentNotNull(client, nameof(client)); + + _client = client.Packages; + _connection = client.Connection; + } + + public IObservablePackageVersionsClient PackageVersions { get; private set; } + + /// + /// List all packages for an organisations, readable by the current user + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Optional: The visibility of the package + public IObservable GetAllForOrg(string org, PackageType packageType, PackageVisibility? packageVisibility = null) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + + var route = ApiUrls.PackagesOrg(org); + var parameters = ParameterBuilder.AddParameter("package_type", packageType).AddOptionalParameter("visibility", packageVisibility); + + return _connection.GetAndFlattenAllPages(route, parameters); + } + + /// + /// Get a specific package for an Organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + public IObservable GetForOrg(string org, PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + return _client.GetForOrg(org, packageType, packageName).ToObservable(); + } + + /// + /// Delete a specific package for an Organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + public IObservable DeleteForOrg(string org, PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + return _client.DeleteForOrg(org, packageType, packageName).ToObservable(); + } + + /// + /// Restore a specific package for an Organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + public IObservable RestoreForOrg(string org, PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + return _client.RestoreForOrg(org, packageType, packageName).ToObservable(); + } + + /// + /// Lists packages owned by the authenticated user within the user's namespace + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Optional: The visibility of the package + public IObservable GetAllForActiveUser(PackageType packageType, PackageVisibility? packageVisibility = null) + { + var route = ApiUrls.PackagesActiveUser(); + var parameters = ParameterBuilder.AddParameter("package_type", packageType).AddOptionalParameter("visibility", packageVisibility); + + return _connection.GetAndFlattenAllPages(route, parameters); + } + + /// + /// Gets a specific package for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + public IObservable GetForActiveUser(PackageType packageType, string packageName) + { + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + return _client.GetForActiveUser(packageType, packageName).ToObservable(); + } + + /// + /// Deletes a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + public IObservable DeleteForActiveUser(PackageType packageType, string packageName) + { + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + return _client.DeleteForActiveUser(packageType, packageName).ToObservable(); + } + + /// + /// Restores a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + public IObservable RestoreForActiveUser(PackageType packageType, string packageName) + { + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + return _client.RestoreForActiveUser(packageType, packageName).ToObservable(); + } + + /// + /// Lists packages owned by the authenticated user within the user's namespace + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Optional: The visibility of the package + public IObservable GetAllForUser(string username, PackageType packageType, PackageVisibility? packageVisibility = null) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + + var route = ApiUrls.PackagesUser(username); + var parameters = ParameterBuilder.AddParameter("package_type", packageType).AddOptionalParameter("visibility", packageVisibility); + + return _connection.GetAndFlattenAllPages(route, parameters); + } + + /// + /// Gets a specific package metadata for a public package owned by a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + public IObservable GetForUser(string username, PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + return _client.GetForUser(username, packageType, packageName).ToObservable(); + } + + /// + /// Deletes an entire package for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + public IObservable DeleteForUser(string username, PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + return _client.DeleteForUser(username, packageType, packageName).ToObservable(); + } + + /// + /// Restores an entire package for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + public IObservable RestoreForUser(string username, PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + return _client.RestoreForUser(username, packageType, packageName).ToObservable(); + } + } +} \ No newline at end of file diff --git a/Octokit.Reactive/IObservableGitHubClient.cs b/Octokit.Reactive/IObservableGitHubClient.cs index e4f91ec0..5563afe5 100644 --- a/Octokit.Reactive/IObservableGitHubClient.cs +++ b/Octokit.Reactive/IObservableGitHubClient.cs @@ -34,5 +34,6 @@ namespace Octokit.Reactive IObservableMigrationClient Migration { get; } IObservableReactionsClient Reaction { get; } IObservableChecksClient Check { get; } + IObservablePackagesClient Packages{ get; } } } \ No newline at end of file diff --git a/Octokit.Reactive/ObservableGitHubClient.cs b/Octokit.Reactive/ObservableGitHubClient.cs index a063faae..e84e191b 100644 --- a/Octokit.Reactive/ObservableGitHubClient.cs +++ b/Octokit.Reactive/ObservableGitHubClient.cs @@ -49,6 +49,7 @@ namespace Octokit.Reactive Migration = new ObservableMigrationClient(gitHubClient); Reaction = new ObservableReactionsClient(gitHubClient); Check = new ObservableChecksClient(gitHubClient); + Packages = new ObservablePackagesClient(gitHubClient); } public IConnection Connection @@ -88,6 +89,7 @@ namespace Octokit.Reactive public IObservableMigrationClient Migration { get; private set; } public IObservableReactionsClient Reaction { get; private set; } public IObservableChecksClient Check { get; private set; } + public IObservablePackagesClient Packages { get; private set; } /// /// Gets the latest API Info - this will be null if no API calls have been made diff --git a/Octokit.Tests.Integration/Clients/PackageVersionsClientTests.cs b/Octokit.Tests.Integration/Clients/PackageVersionsClientTests.cs new file mode 100644 index 00000000..2571500d --- /dev/null +++ b/Octokit.Tests.Integration/Clients/PackageVersionsClientTests.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using Xunit; + +namespace Octokit.Tests.Integration.Clients +{ + public class PackageVersionsClientTests + { + public class TheGetAllMethod + { + [IntegrationTest(Skip = "Cannot create packages as part of this test, so can never succeed")] + public async Task ReturnsAllPackageVersions() + { + var github = Helper.GetAuthenticatedClient(); + + var result = await github.Packages.PackageVersions.GetAllForOrg(Helper.Organization, PackageType.Container, "asd"); + + Assert.NotEmpty(result); + } + } + + public class TheGetMethod + { + [IntegrationTest(Skip = "Cannot create packages as part of this test, so can never succeed")] + public async Task ReturnsAPackages() + { + var github = Helper.GetAuthenticatedClient(); + + var result = await github.Packages.PackageVersions.GetForOrg(Helper.Organization, PackageType.Container, "asd", 1); + + Assert.NotNull(result); + } + } + } +} \ No newline at end of file diff --git a/Octokit.Tests.Integration/Clients/PackagesClientTests.cs b/Octokit.Tests.Integration/Clients/PackagesClientTests.cs new file mode 100644 index 00000000..f1e2ab00 --- /dev/null +++ b/Octokit.Tests.Integration/Clients/PackagesClientTests.cs @@ -0,0 +1,34 @@ +using System.Threading.Tasks; +using Xunit; + +namespace Octokit.Tests.Integration.Clients +{ + public class PackagesClientTests + { + public class TheGetAllMethod + { + [IntegrationTest(Skip = "Cannot create packages as part of this test, so can never succeed")] + public async Task ReturnsAllPackages() + { + var github = Helper.GetAuthenticatedClient(); + + var result = await github.Packages.GetAllForOrg(Helper.Organization, PackageType.Container); + + Assert.NotEmpty(result); + } + } + + public class TheGetMethod + { + [IntegrationTest(Skip = "Cannot create packages as part of this test, so can never succeed")] + public async Task ReturnsAPackages() + { + var github = Helper.GetAuthenticatedClient(); + + var result = await github.Packages.GetForOrg(Helper.Organization, PackageType.Container, "asd"); + + Assert.NotNull(result); + } + } + } +} \ No newline at end of file diff --git a/Octokit.Tests/Clients/PackageVersionsClientTests.cs b/Octokit.Tests/Clients/PackageVersionsClientTests.cs new file mode 100644 index 00000000..2e75aa33 --- /dev/null +++ b/Octokit.Tests/Clients/PackageVersionsClientTests.cs @@ -0,0 +1,395 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using NSubstitute; +using Xunit; + +namespace Octokit.Tests.Clients +{ + public class PackageVersionsClientTests + { + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new PackageVersionsClient(null)); + } + } + + public class TheGetAllForOrgMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.GetAllForOrg("fake", PackageType.RubyGems, "name"); + + connection.Received().GetAll(Arg.Is(u => + u.ToString() == "/orgs/fake/packages/rubygems/name/versions"), + Arg.Is>(d => d.ContainsKey("state")), + Args.ApiOptions); + } + + [Fact] + public async Task RequestsCorrectUrlWithOptionalParameter() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.GetAllForOrg("fake", PackageType.RubyGems, "name", PackageVersionState.Deleted); + + var calls = connection.ReceivedCalls(); + connection.Received().GetAll(Arg.Is(u => + u.ToString() == "/orgs/fake/packages/rubygems/name/versions"), + Arg.Is>(d => d.ContainsKey("state") && d["state"] == "deleted"), + Args.ApiOptions); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await Assert.ThrowsAsync(() => client.GetAllForOrg(null, PackageType.Npm, "asd")); + await Assert.ThrowsAsync(() => client.GetAllForOrg("", PackageType.Npm, "asd")); + + await Assert.ThrowsAsync(() => client.GetAllForOrg("owner", PackageType.Npm, null)); + await Assert.ThrowsAsync(() => client.GetAllForOrg("owner", PackageType.Npm, "")); + } + } + + public class TheGetForOrgMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.GetForOrg("fake", PackageType.Npm, "name", 5); + + connection.Received().Get(Arg.Is(u => u.ToString() == "/orgs/fake/packages/npm/name/versions/5")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackageVersionsClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.GetForOrg(null, PackageType.Npm, "asd", 5)); + await Assert.ThrowsAsync(() => client.GetForOrg("", PackageType.Npm, "asd", 5)); + + await Assert.ThrowsAsync(() => client.GetForOrg("owner", PackageType.Npm, null, 5)); + await Assert.ThrowsAsync(() => client.GetForOrg("owner", PackageType.Npm, "", 5)); + + await Assert.ThrowsAsync(() => client.GetForOrg("owner", PackageType.Npm, "", 0)); + } + } + + public class TheDeleteForOrgMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.DeleteForOrg("fake", PackageType.Npm, "name", 5); + + connection.Received().Delete(Arg.Is(u => u.ToString() == "/orgs/fake/packages/npm/name/versions/5")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackageVersionsClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.DeleteForOrg(null, PackageType.Npm, "asd", 5)); + await Assert.ThrowsAsync(() => client.DeleteForOrg("", PackageType.Npm, "asd", 5)); + + await Assert.ThrowsAsync(() => client.DeleteForOrg("owner", PackageType.Npm, null, 5)); + await Assert.ThrowsAsync(() => client.DeleteForOrg("owner", PackageType.Npm, "", 5)); + + await Assert.ThrowsAsync(() => client.DeleteForOrg("owner", PackageType.Npm, "", 0)); + } + } + + public class TheRestoreForOrgMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.RestoreForOrg("fake", PackageType.Npm, "name", 5); + + connection.Received().Post(Arg.Is(u => u.ToString() == "/orgs/fake/packages/npm/name/versions/5/restore")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackageVersionsClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.RestoreForOrg(null, PackageType.Npm, "asd", 5)); + await Assert.ThrowsAsync(() => client.RestoreForOrg("", PackageType.Npm, "asd", 5)); + + await Assert.ThrowsAsync(() => client.RestoreForOrg("owner", PackageType.Npm, null, 5)); + await Assert.ThrowsAsync(() => client.RestoreForOrg("owner", PackageType.Npm, "", 5)); + + await Assert.ThrowsAsync(() => client.RestoreForOrg("owner", PackageType.Npm, "", 0)); + } + } + + public class TheGetAllForActiveUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.GetAllForActiveUser(PackageType.RubyGems, "name"); + + connection.Received().GetAll(Arg.Is(u => + u.ToString() == "/user/packages/rubygems/name/versions"), + Arg.Is>(d => d.ContainsKey("state")), + Args.ApiOptions); + } + + [Fact] + public async Task RequestsCorrectUrlWithOptionalParameter() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.GetAllForActiveUser(PackageType.RubyGems, "name", PackageVersionState.Deleted); + + var calls = connection.ReceivedCalls(); + connection.Received().GetAll(Arg.Is(u => + u.ToString() == "/user/packages/rubygems/name/versions"), + Arg.Is>(d => d.ContainsKey("state") && d["state"] == "deleted"), + Args.ApiOptions); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await Assert.ThrowsAsync(() => client.GetAllForActiveUser(PackageType.Npm, null)); + await Assert.ThrowsAsync(() => client.GetAllForActiveUser(PackageType.Npm, "")); + } + } + + public class TheGetForActiveUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.GetForActiveUser(PackageType.Npm, "name", 5); + + connection.Received().Get(Arg.Is(u => u.ToString() == "/user/packages/npm/name/versions/5")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackageVersionsClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.GetForActiveUser(PackageType.Npm, null, 5)); + await Assert.ThrowsAsync(() => client.GetForActiveUser(PackageType.Npm, "", 5)); + + await Assert.ThrowsAsync(() => client.GetForActiveUser(PackageType.Npm, "", 0)); + } + } + + public class TheDeleteForActiveUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.DeleteForActiveUser(PackageType.Npm, "name", 5); + + connection.Received().Delete(Arg.Is(u => u.ToString() == "/user/packages/npm/name/versions/5")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackageVersionsClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.DeleteForActiveUser(PackageType.Npm, null, 5)); + await Assert.ThrowsAsync(() => client.DeleteForActiveUser(PackageType.Npm, "", 5)); + + await Assert.ThrowsAsync(() => client.DeleteForActiveUser(PackageType.Npm, "", 0)); + } + } + + public class TheRestoreForActiveUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.RestoreForActiveUser(PackageType.Npm, "name", 5); + + connection.Received().Post(Arg.Is(u => u.ToString() == "/user/packages/npm/name/versions/5/restore")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackageVersionsClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.RestoreForActiveUser(PackageType.Npm, null, 5)); + await Assert.ThrowsAsync(() => client.RestoreForActiveUser(PackageType.Npm, "", 5)); + + await Assert.ThrowsAsync(() => client.RestoreForActiveUser(PackageType.Npm, "", 0)); + } + } + + public class TheGetAllForUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.GetAllForUser("fake", PackageType.RubyGems, "name"); + + connection.Received().GetAll(Arg.Is(u => + u.ToString() == "/users/fake/packages/rubygems/name/versions"), + Arg.Is>(d => d.ContainsKey("state")), + Args.ApiOptions); + } + + [Fact] + public async Task RequestsCorrectUrlWithOptionalParameter() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.GetAllForUser("fake", PackageType.RubyGems, "name", PackageVersionState.Deleted); + + var calls = connection.ReceivedCalls(); + connection.Received().GetAll(Arg.Is(u => + u.ToString() == "/users/fake/packages/rubygems/name/versions"), + Arg.Is>(d => d.ContainsKey("state") && d["state"] == "deleted"), + Args.ApiOptions); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await Assert.ThrowsAsync(() => client.GetAllForUser(null, PackageType.Npm, "asd")); + await Assert.ThrowsAsync(() => client.GetAllForUser("", PackageType.Npm, "asd")); + + await Assert.ThrowsAsync(() => client.GetAllForUser("owner", PackageType.Npm, null)); + await Assert.ThrowsAsync(() => client.GetAllForUser("owner", PackageType.Npm, "")); + } + } + + public class TheGetForUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.GetForUser("fake", PackageType.Npm, "name", 5); + + connection.Received().Get(Arg.Is(u => u.ToString() == "/users/fake/packages/npm/name/versions/5")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackageVersionsClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.GetForUser(null, PackageType.Npm, "asd", 5)); + await Assert.ThrowsAsync(() => client.GetForUser("", PackageType.Npm, "asd", 5)); + + await Assert.ThrowsAsync(() => client.GetForUser("owner", PackageType.Npm, null, 5)); + await Assert.ThrowsAsync(() => client.GetForUser("owner", PackageType.Npm, "", 5)); + + await Assert.ThrowsAsync(() => client.GetForUser("owner", PackageType.Npm, "", 0)); + } + } + + public class TheDeleteForUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.DeleteForUser("fake", PackageType.Npm, "name", 5); + + connection.Received().Delete(Arg.Is(u => u.ToString() == "/users/fake/packages/npm/name/versions/5")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackageVersionsClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.DeleteForUser(null, PackageType.Npm, "asd", 5)); + await Assert.ThrowsAsync(() => client.DeleteForUser("", PackageType.Npm, "asd", 5)); + + await Assert.ThrowsAsync(() => client.DeleteForUser("owner", PackageType.Npm, null, 5)); + await Assert.ThrowsAsync(() => client.DeleteForUser("owner", PackageType.Npm, "", 5)); + + await Assert.ThrowsAsync(() => client.DeleteForUser("owner", PackageType.Npm, "", 0)); + } + } + + public class TheRestoreForUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackageVersionsClient(connection); + + await client.RestoreForUser("fake", PackageType.Npm, "name", 5); + + connection.Received().Post(Arg.Is(u => u.ToString() == "/users/fake/packages/npm/name/versions/5/restore")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackageVersionsClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.RestoreForUser(null, PackageType.Npm, "asd", 5)); + await Assert.ThrowsAsync(() => client.RestoreForUser("", PackageType.Npm, "asd", 5)); + + await Assert.ThrowsAsync(() => client.RestoreForUser("owner", PackageType.Npm, null, 5)); + await Assert.ThrowsAsync(() => client.RestoreForUser("owner", PackageType.Npm, "", 5)); + + await Assert.ThrowsAsync(() => client.RestoreForUser("owner", PackageType.Npm, "", 0)); + } + } + } +} diff --git a/Octokit.Tests/Clients/PackagesClientTests.cs b/Octokit.Tests/Clients/PackagesClientTests.cs new file mode 100644 index 00000000..1b056c30 --- /dev/null +++ b/Octokit.Tests/Clients/PackagesClientTests.cs @@ -0,0 +1,344 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using NSubstitute; +using Xunit; + +namespace Octokit.Tests.Clients +{ + public class PackagesClientTests + { + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new PackagesClient(null)); + } + } + + public class TheGetAllForOrgMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.GetAllForOrg("fake", PackageType.RubyGems); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "/orgs/fake/packages"), Arg.Is>(d => d.ContainsKey("package_type"))); + } + + [Fact] + public async Task RequestsCorrectUrlWithOptionalParameter() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.GetAllForOrg("fake", PackageType.RubyGems, PackageVisibility.Public); + + var calls = connection.ReceivedCalls(); + connection.Received().GetAll(Arg.Is(u => u.ToString() == "/orgs/fake/packages"), Arg.Is>(d => d.ContainsKey("package_type") && d.ContainsKey("visibility"))); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await Assert.ThrowsAsync(() => client.GetAllForOrg(null, PackageType.Nuget)); + await Assert.ThrowsAsync(() => client.GetAllForOrg("", PackageType.Nuget)); + } + } + + public class TheGetForOrgMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.GetForOrg("fake", PackageType.Npm, "name"); + + connection.Received().Get(Arg.Is(u => u.ToString() == "/orgs/fake/packages/npm/name")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackagesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.GetForOrg(null, PackageType.Npm, "asd")); + await Assert.ThrowsAsync(() => client.GetForOrg("", PackageType.Npm, "asd")); + + await Assert.ThrowsAsync(() => client.GetForOrg("owner", PackageType.Npm, null)); + await Assert.ThrowsAsync(() => client.GetForOrg("owner", PackageType.Npm, "")); + } + } + + public class TheDeleteForOrgMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.DeleteForOrg("fake", PackageType.Npm, "name"); + + connection.Received().Delete(Arg.Is(u => u.ToString() == "/orgs/fake/packages/npm/name")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackagesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.DeleteForOrg(null, PackageType.Npm, "asd")); + await Assert.ThrowsAsync(() => client.DeleteForOrg("", PackageType.Npm, "asd")); + + await Assert.ThrowsAsync(() => client.DeleteForOrg("owner", PackageType.Npm, null)); + await Assert.ThrowsAsync(() => client.DeleteForOrg("owner", PackageType.Npm, "")); + } + } + + public class TheRestoreForOrgMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.RestoreForOrg("fake", PackageType.Npm, "name"); + + connection.Received().Post(Arg.Is(u => u.ToString() == "/orgs/fake/packages/npm/name/restore")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackagesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.RestoreForOrg(null, PackageType.Npm, "asd")); + await Assert.ThrowsAsync(() => client.RestoreForOrg("", PackageType.Npm, "asd")); + + await Assert.ThrowsAsync(() => client.RestoreForOrg("owner", PackageType.Npm, null)); + await Assert.ThrowsAsync(() => client.RestoreForOrg("owner", PackageType.Npm, "")); + } + } + + public class TheGetAllForActiveUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.GetAllForActiveUser(PackageType.RubyGems); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "/user/packages"), Arg.Is>(d => d.ContainsKey("package_type"))); + } + + [Fact] + public async Task RequestsCorrectUrlWithOptionalParameter() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.GetAllForActiveUser(PackageType.RubyGems, PackageVisibility.Public); + + var calls = connection.ReceivedCalls(); + connection.Received().GetAll(Arg.Is(u => u.ToString() == "/user/packages"), Arg.Is>(d => d.ContainsKey("package_type") && d.ContainsKey("visibility"))); + } + } + + public class TheGetForActiveUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.GetForActiveUser(PackageType.Npm, "name"); + + connection.Received().Get(Arg.Is(u => u.ToString() == "/user/packages/npm/name")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackagesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.GetForActiveUser(PackageType.Npm, null)); + await Assert.ThrowsAsync(() => client.GetForActiveUser(PackageType.Npm, "")); + } + } + + public class TheDeleteForActiveUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.DeleteForActiveUser(PackageType.Npm, "name"); + + connection.Received().Delete(Arg.Is(u => u.ToString() == "/user/packages/npm/name")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackagesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.DeleteForActiveUser(PackageType.Npm, null)); + await Assert.ThrowsAsync(() => client.DeleteForActiveUser(PackageType.Npm, "")); + } + } + + public class TheRestoreForActiveUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.RestoreForActiveUser(PackageType.Npm, "name"); + + connection.Received().Post(Arg.Is(u => u.ToString() == "/user/packages/npm/name/restore")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackagesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.RestoreForActiveUser(PackageType.Npm, null)); + await Assert.ThrowsAsync(() => client.RestoreForActiveUser(PackageType.Npm, "")); + } + } + + public class TheGetAllForUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.GetAllForUser("fake", PackageType.RubyGems); + + connection.Received().GetAll(Arg.Is(u => u.ToString() == "/users/fake/packages"), Arg.Is>(d => d.ContainsKey("package_type"))); + } + + [Fact] + public async Task RequestsCorrectUrlWithOptionalParameter() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.GetAllForUser("fake", PackageType.RubyGems, PackageVisibility.Public); + + var calls = connection.ReceivedCalls(); + connection.Received().GetAll(Arg.Is(u => u.ToString() == "/users/fake/packages"), Arg.Is>(d => d.ContainsKey("package_type") && d.ContainsKey("visibility"))); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await Assert.ThrowsAsync(() => client.GetAllForUser(null, PackageType.Nuget)); + await Assert.ThrowsAsync(() => client.GetAllForUser("", PackageType.Nuget)); + } + } + + public class TheGetForUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.GetForUser("fake", PackageType.Npm, "name"); + + connection.Received().Get(Arg.Is(u => u.ToString() == "/users/fake/packages/npm/name")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackagesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.GetForUser(null, PackageType.Npm, "asd")); + await Assert.ThrowsAsync(() => client.GetForUser("", PackageType.Npm, "asd")); + + await Assert.ThrowsAsync(() => client.GetForUser("owner", PackageType.Npm, null)); + await Assert.ThrowsAsync(() => client.GetForUser("owner", PackageType.Npm, "")); + } + } + + public class TheDeleteForUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.DeleteForUser("fake", PackageType.Npm, "name"); + + connection.Received().Delete(Arg.Is(u => u.ToString() == "/users/fake/packages/npm/name")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackagesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.DeleteForUser(null, PackageType.Npm, "asd")); + await Assert.ThrowsAsync(() => client.DeleteForUser("", PackageType.Npm, "asd")); + + await Assert.ThrowsAsync(() => client.DeleteForUser("owner", PackageType.Npm, null)); + await Assert.ThrowsAsync(() => client.DeleteForUser("owner", PackageType.Npm, "")); + } + } + + public class TheRestoreForUserMethod + { + [Fact] + public async Task RequestsCorrectUrl() + { + var connection = Substitute.For(); + var client = new PackagesClient(connection); + + await client.RestoreForUser("fake", PackageType.Npm, "name"); + + connection.Received().Post(Arg.Is(u => u.ToString() == "/users/fake/packages/npm/name/restore")); + } + + [Fact] + public async Task EnsuresNonNullArguments() + { + var client = new PackagesClient(Substitute.For()); + + await Assert.ThrowsAsync(() => client.RestoreForUser(null, PackageType.Npm, "asd")); + await Assert.ThrowsAsync(() => client.RestoreForUser("", PackageType.Npm, "asd")); + + await Assert.ThrowsAsync(() => client.RestoreForUser("owner", PackageType.Npm, null)); + await Assert.ThrowsAsync(() => client.RestoreForUser("owner", PackageType.Npm, "")); + } + } + + } +} diff --git a/Octokit.Tests/Reactive/ObservablePackageVersionsTests.cs b/Octokit.Tests/Reactive/ObservablePackageVersionsTests.cs new file mode 100644 index 00000000..0ba5cc33 --- /dev/null +++ b/Octokit.Tests/Reactive/ObservablePackageVersionsTests.cs @@ -0,0 +1,146 @@ +using System; +using System.Collections.Generic; +using NSubstitute; +using Octokit.Reactive; +using Xunit; + +namespace Octokit.Tests.Reactive +{ + public class ObservablePackageVersionsTests + { + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new ObservablePackageVersionsClient(null)); + } + } + + public class TheGetAllMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackageVersionsClient(gitHubClient); + + client.GetAllForOrg("fake", PackageType.RubyGems, "name"); + + gitHubClient.Connection.Received().Get>( + new Uri("/orgs/fake/packages/rubygems/name/versions", UriKind.Relative), + Arg.Is>(d => d.ContainsKey("state"))); + } + + [Fact] + public void RequestsCorrectUrlWithOptionalParameter() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackageVersionsClient(gitHubClient); + + client.GetAllForOrg("fake", PackageType.RubyGems, "name", PackageVersionState.Deleted); + + gitHubClient.Connection.Received().Get>( + Arg.Is(u => u.ToString() == "/orgs/fake/packages/rubygems/name/versions"), + Arg.Is>(d => d.ContainsKey("state") && d["state"] == "deleted")); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackageVersionsClient(Substitute.For()); + + Assert.Throws(() => client.GetAllForOrg(null, PackageType.Nuget, "name")); + Assert.Throws(() => client.GetAllForOrg("", PackageType.Nuget, "name")); + + Assert.Throws(() => client.GetAllForOrg("fake", PackageType.Nuget, null)); + Assert.Throws(() => client.GetAllForOrg("fake", PackageType.Nuget, "")); + } + } + + public class TheGetMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackageVersionsClient(gitHubClient); + + client.GetForOrg("fake", PackageType.Npm, "name", 5); + + gitHubClient.Packages.PackageVersions.Received().GetForOrg("fake", PackageType.Npm, "name", 5); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackageVersionsClient(Substitute.For()); + + Assert.Throws(() => client.GetForOrg(null, PackageType.Npm, "asd", 5)); + Assert.Throws(() => client.GetForOrg("", PackageType.Npm, "asd", 5)); + + Assert.Throws(() => client.GetForOrg("owner", PackageType.Npm, null, 5)); + Assert.Throws(() => client.GetForOrg("owner", PackageType.Npm, "", 5)); + + Assert.Throws(() => client.GetForOrg("owner", PackageType.Npm, "asd", 0)); + } + } + + public class TheDeleteMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackageVersionsClient(gitHubClient); + + client.DeleteForOrg("fake", PackageType.Npm, "name", 5); + + gitHubClient.Packages.PackageVersions.Received(1).DeleteForOrg("fake", PackageType.Npm, "name", 5); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackageVersionsClient(Substitute.For()); + + Assert.Throws(() => client.DeleteForOrg(null, PackageType.Npm, "asd", 5)); + Assert.Throws(() => client.DeleteForOrg("", PackageType.Npm, "asd", 5)); + + Assert.Throws(() => client.DeleteForOrg("owner", PackageType.Npm, null, 5)); + Assert.Throws(() => client.DeleteForOrg("owner", PackageType.Npm, "", 5)); + + Assert.Throws(() => client.DeleteForOrg("owner", PackageType.Npm, "asd", 0)); + } + } + + public class TheRestoreMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackageVersionsClient(gitHubClient); + + client.RestoreForOrg("fake", PackageType.Npm, "name", 5); + + gitHubClient.Packages.PackageVersions.Received(1).RestoreForOrg("fake", PackageType.Npm, "name", 5); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackageVersionsClient(Substitute.For()); + + Assert.Throws(() => client.RestoreForOrg(null, PackageType.Npm, "asd", 5)); + Assert.Throws(() => client.RestoreForOrg("", PackageType.Npm, "asd", 5)); + + Assert.Throws(() => client.RestoreForOrg("owner", PackageType.Npm, null, 5)); + Assert.Throws(() => client.RestoreForOrg("owner", PackageType.Npm, "", 5)); + + Assert.Throws(() => client.RestoreForOrg("owner", PackageType.Npm, "asd", 0)); + } + } + } + +} diff --git a/Octokit.Tests/Reactive/ObservablePackagesTests.cs b/Octokit.Tests/Reactive/ObservablePackagesTests.cs new file mode 100644 index 00000000..996da9b7 --- /dev/null +++ b/Octokit.Tests/Reactive/ObservablePackagesTests.cs @@ -0,0 +1,350 @@ +using System; +using System.Collections.Generic; +using NSubstitute; +using Octokit.Reactive; +using Xunit; + +namespace Octokit.Tests.Reactive +{ + public class ObservablePackagesTests + { + public class TheCtor + { + [Fact] + public void EnsuresNonNullArguments() + { + Assert.Throws(() => new ObservablePackagesClient(null)); + } + } + + public class TheGetAllForOrgMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.GetAllForOrg("fake", PackageType.RubyGems); + + gitHubClient.Connection.Received(1).Get>( + new Uri("/orgs/fake/packages", UriKind.Relative), + Arg.Is>(d => d.ContainsKey("package_type"))); + } + + [Fact] + public void RequestsCorrectUrlWithOptionalParameter() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.GetAllForOrg("fake", PackageType.RubyGems, PackageVisibility.Public); + + gitHubClient.Connection.Received().Get>( + Arg.Is(u => u.ToString() == "/orgs/fake/packages"), + Arg.Is>(d => d.ContainsKey("package_type") && d.ContainsKey("visibility"))); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackagesClient(Substitute.For()); + + Assert.Throws(() => client.GetAllForOrg(null, PackageType.Nuget)); + Assert.Throws(() => client.GetAllForOrg("", PackageType.Nuget)); + } + } + + public class TheGetForOrgMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.GetForOrg("fake", PackageType.Npm, "name"); + + gitHubClient.Packages.Received().GetForOrg("fake", PackageType.Npm, "name"); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackagesClient(Substitute.For()); + + Assert.Throws(() => client.GetForOrg(null, PackageType.Npm, "asd")); + Assert.Throws(() => client.GetForOrg("", PackageType.Npm, "asd")); + + Assert.Throws(() => client.GetForOrg("owner", PackageType.Npm, null)); + Assert.Throws(() => client.GetForOrg("owner", PackageType.Npm, "")); + } + } + + public class TheDeleteForOrgMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.DeleteForOrg("fake", PackageType.Npm, "name"); + + gitHubClient.Packages.Received(1).DeleteForOrg("fake", PackageType.Npm, "name"); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackagesClient(Substitute.For()); + + Assert.Throws(() => client.DeleteForOrg(null, PackageType.Npm, "asd")); + Assert.Throws(() => client.DeleteForOrg("", PackageType.Npm, "asd")); + + Assert.Throws(() => client.DeleteForOrg("owner", PackageType.Npm, null)); + Assert.Throws(() => client.DeleteForOrg("owner", PackageType.Npm, "")); + } + } + + public class TheRestoreForOrgMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.RestoreForOrg("fake", PackageType.Npm, "name"); + + gitHubClient.Packages.Received(1).RestoreForOrg("fake", PackageType.Npm, "name"); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackagesClient(Substitute.For()); + + Assert.Throws(() => client.RestoreForOrg(null, PackageType.Npm, "asd")); + Assert.Throws(() => client.RestoreForOrg("", PackageType.Npm, "asd")); + + Assert.Throws(() => client.RestoreForOrg("owner", PackageType.Npm, null)); + Assert.Throws(() => client.RestoreForOrg("owner", PackageType.Npm, "")); + } + + public class TheGetAllForActiveUserMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.GetAllForActiveUser(PackageType.RubyGems); + + gitHubClient.Connection.Received(1).Get>( + new Uri("/user/packages", UriKind.Relative), + Arg.Is>(d => d.ContainsKey("package_type"))); + } + + [Fact] + public void RequestsCorrectUrlWithOptionalParameter() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.GetAllForActiveUser(PackageType.RubyGems, PackageVisibility.Public); + + gitHubClient.Connection.Received().Get>( + Arg.Is(u => u.ToString() == "/user/packages"), + Arg.Is>(d => d.ContainsKey("package_type") && d.ContainsKey("visibility"))); + } + } + + public class TheGetForActiveUserMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.GetForActiveUser(PackageType.Npm, "name"); + + gitHubClient.Packages.Received().GetForActiveUser(PackageType.Npm, "name"); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackagesClient(Substitute.For()); + + Assert.Throws(() => client.GetForActiveUser(PackageType.Npm, null)); + Assert.Throws(() => client.GetForActiveUser(PackageType.Npm, "")); + } + } + + public class TheDeleteForActiveUserMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.DeleteForActiveUser(PackageType.Npm, "name"); + + gitHubClient.Packages.Received(1).DeleteForActiveUser(PackageType.Npm, "name"); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackagesClient(Substitute.For()); + + Assert.Throws(() => client.DeleteForActiveUser(PackageType.Npm, null)); + Assert.Throws(() => client.DeleteForActiveUser(PackageType.Npm, "")); + } + } + + public class TheRestoreForActiveUserMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.RestoreForActiveUser(PackageType.Npm, "name"); + + gitHubClient.Packages.Received(1).RestoreForActiveUser(PackageType.Npm, "name"); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackagesClient(Substitute.For()); + + Assert.Throws(() => client.RestoreForActiveUser(PackageType.Npm, null)); + Assert.Throws(() => client.RestoreForActiveUser(PackageType.Npm, "")); + } + } + + public class TheGetAllForUserMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.GetAllForUser("fake", PackageType.RubyGems); + + gitHubClient.Connection.Received(1).Get>( + new Uri("/users/fake/packages", UriKind.Relative), + Arg.Is>(d => d.ContainsKey("package_type"))); + } + + [Fact] + public void RequestsCorrectUrlWithOptionalParameter() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.GetAllForUser("fake", PackageType.RubyGems, PackageVisibility.Public); + + gitHubClient.Connection.Received().Get>( + Arg.Is(u => u.ToString() == "/users/fake/packages"), + Arg.Is>(d => d.ContainsKey("package_type") && d.ContainsKey("visibility"))); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackagesClient(Substitute.For()); + + Assert.Throws(() => client.GetAllForUser(null, PackageType.Nuget)); + Assert.Throws(() => client.GetAllForUser("", PackageType.Nuget)); + } + } + + public class TheGetForUserMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.GetForUser("fake", PackageType.Npm, "name"); + + gitHubClient.Packages.Received().GetForUser("fake", PackageType.Npm, "name"); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackagesClient(Substitute.For()); + + Assert.Throws(() => client.GetForUser(null, PackageType.Npm, "asd")); + Assert.Throws(() => client.GetForUser("", PackageType.Npm, "asd")); + + Assert.Throws(() => client.GetForUser("owner", PackageType.Npm, null)); + Assert.Throws(() => client.GetForUser("owner", PackageType.Npm, "")); + } + } + + public class TheDeleteForUserMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.DeleteForUser("fake", PackageType.Npm, "name"); + + gitHubClient.Packages.Received(1).DeleteForUser("fake", PackageType.Npm, "name"); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackagesClient(Substitute.For()); + + Assert.Throws(() => client.DeleteForUser(null, PackageType.Npm, "asd")); + Assert.Throws(() => client.DeleteForUser("", PackageType.Npm, "asd")); + + Assert.Throws(() => client.DeleteForUser("owner", PackageType.Npm, null)); + Assert.Throws(() => client.DeleteForUser("owner", PackageType.Npm, "")); + } + } + + public class TheRestoreForUserMethod + { + [Fact] + public void RequestsCorrectUrl() + { + var gitHubClient = Substitute.For(); + var client = new ObservablePackagesClient(gitHubClient); + + client.RestoreForUser("fake", PackageType.Npm, "name"); + + gitHubClient.Packages.Received(1).RestoreForUser("fake", PackageType.Npm, "name"); + } + + [Fact] + public void EnsuresNonNullArguments() + { + var client = new ObservablePackagesClient(Substitute.For()); + + Assert.Throws(() => client.RestoreForUser(null, PackageType.Npm, "asd")); + Assert.Throws(() => client.RestoreForUser("", PackageType.Npm, "asd")); + + Assert.Throws(() => client.RestoreForUser("owner", PackageType.Npm, null)); + Assert.Throws(() => client.RestoreForUser("owner", PackageType.Npm, "")); + } + } + } + } +} diff --git a/Octokit/Clients/IPackageVersionsClient.cs b/Octokit/Clients/IPackageVersionsClient.cs new file mode 100644 index 00000000..dd877f78 --- /dev/null +++ b/Octokit/Clients/IPackageVersionsClient.cs @@ -0,0 +1,151 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + public interface IPackageVersionsClient + { + /// + /// List all versions of a package. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Optional: Return packages with a state. Defaults to Active + /// Optional: Paging options + Task> GetAllForOrg(string org, PackageType packageType, string packageName, PackageVersionState state = PackageVersionState.Active, ApiOptions options = null); + + /// + /// Get a specific version of a package. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + Task GetForOrg(string org, PackageType packageType, string packageName, int packageVersionId); + + /// + /// Deletes a specific package version in an organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + Task DeleteForOrg(string org, PackageType packageType, string packageName, int packageVersionId); + + /// + /// Restores a specific package version in an organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + Task RestoreForOrg(string org, PackageType packageType, string packageName, int packageVersionId); + + /// + /// Returns all package versions for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Optional: Return packages with a state. Defaults to Active + /// Optional: Paging options + Task> GetAllForActiveUser(PackageType packageType, string packageName, PackageVersionState state = PackageVersionState.Active, ApiOptions options = null); + + /// + /// Gets a specific package version for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + Task GetForActiveUser(PackageType packageType, string packageName, int packageVersionId); + + /// + /// Deletes a specific package version for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + Task DeleteForActiveUser(PackageType packageType, string packageName, int packageVersionId); + + /// + /// Restores a package version owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + Task RestoreForActiveUser(PackageType packageType, string packageName, int packageVersionId); + + /// + /// Returns all package versions for a public package owned by a specified user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Optional: Return packages with a state. Defaults to Active + /// Optional: Paging options + Task> GetAllForUser(string username, PackageType packageType, string packageName, PackageVersionState state = PackageVersionState.Active, ApiOptions options = null); + + /// + /// Gets a specific package version for a public package owned by a specified user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + Task GetForUser(string username, PackageType packageType, string packageName, int packageVersionId); + + /// + /// Deletes a specific package version for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + Task DeleteForUser(string username, PackageType packageType, string packageName, int packageVersionId); + + /// + /// Restores a specific package version for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + Task RestoreForUser(string username, PackageType packageType, string packageName, int packageVersionId); + } +} \ No newline at end of file diff --git a/Octokit/Clients/IPackagesClient.cs b/Octokit/Clients/IPackagesClient.cs new file mode 100644 index 00000000..25dac896 --- /dev/null +++ b/Octokit/Clients/IPackagesClient.cs @@ -0,0 +1,141 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + public interface IPackagesClient + { + IPackageVersionsClient PackageVersions { get; } + + /// + /// List all packages for an organisations, readable by the current user + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Optional: The visibility of the package + [ExcludeFromPaginationApiOptionsConventionTest("No api options available according to the documentation")] + Task> GetAllForOrg(string org, PackageType packageType, PackageVisibility? packageVisibility = null); + + /// + /// Get a specific package for an Organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + Task GetForOrg(string org, PackageType packageType, string packageName); + + /// + /// Delete a specific package for an Organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + Task DeleteForOrg(string org, PackageType packageType, string packageName); + + /// + /// Restore a specific package for an Organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + Task RestoreForOrg(string org, PackageType packageType, string packageName); + + /// + /// Lists packages owned by the authenticated user within the user's namespace + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Optional: The visibility of the package + [ExcludeFromPaginationApiOptionsConventionTest("No api options available according to the documentation")] + Task> GetAllForActiveUser(PackageType packageType, PackageVisibility? packageVisibility = null); + + /// + /// Gets a specific package for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + Task GetForActiveUser(PackageType packageType, string packageName); + + /// + /// Deletes a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + Task DeleteForActiveUser(PackageType packageType, string packageName); + + /// + /// Restores a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + Task RestoreForActiveUser(PackageType packageType, string packageName); + + /// + /// Lists packages owned by the authenticated user within the user's namespace + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Optional: The visibility of the package + [ExcludeFromPaginationApiOptionsConventionTest("No api options available according to the documentation")] + Task> GetAllForUser(string username, PackageType packageType, PackageVisibility? packageVisibility = null); + + /// + /// Gets a specific package metadata for a public package owned by a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + Task GetForUser(string username, PackageType packageType, string packageName); + + /// + /// Deletes an entire package for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + Task DeleteForUser(string username, PackageType packageType, string packageName); + + /// + /// Restores an entire package for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + Task RestoreForUser(string username, PackageType packageType, string packageName); + } +} \ No newline at end of file diff --git a/Octokit/Clients/PackageVersionsClient.cs b/Octokit/Clients/PackageVersionsClient.cs new file mode 100644 index 00000000..023cb18f --- /dev/null +++ b/Octokit/Clients/PackageVersionsClient.cs @@ -0,0 +1,283 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + public class PackageVersionsClient : ApiClient, IPackageVersionsClient + { + public PackageVersionsClient(IApiConnection apiConnection) : base(apiConnection) + { + } + + #region Organization + /// + /// List all versions of a package. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Optional: Return packages with a state. Defaults to Active + /// Optional: Paging options + [ManualRoute("GET", "/orgs/{org}/packages/{package_type}/{package_name}/versions")] + public Task> GetAllForOrg(string org, PackageType packageType, string packageName, PackageVersionState state = PackageVersionState.Active, ApiOptions options = null) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.ApiOptionsNotNull(ref options); + + var route = ApiUrls.PackageVersionsOrg(org, packageType, packageName); + var parameters = ParameterBuilder.AddParameter("state", state); + + return ApiConnection.GetAll(route, parameters, options); + } + + /// + /// Get a specific version of a package. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + [ManualRoute("GET", "/orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}")] + public Task GetForOrg(string org, PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + var route = ApiUrls.PackageVersionOrg(org, packageType, packageName, packageVersionId); + + return ApiConnection.Get(route); + } + + /// + /// Deletes a specific package version in an organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + [ManualRoute("DELETE", "/orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}")] + public Task DeleteForOrg(string org, PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + var route = ApiUrls.PackageVersionOrg(org, packageType, packageName, packageVersionId); + return ApiConnection.Delete(route); + } + + /// + /// Restores a specific package version in an organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + [ManualRoute("POST", "/orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore")] + public Task RestoreForOrg(string org, PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + var route = ApiUrls.PackageVersionRestoreOrg(org, packageType, packageName, packageVersionId); + + return ApiConnection.Post(route); + } + #endregion + + #region Active User + /// + /// Returns all package versions for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Optional: Return packages with a state. Defaults to Active + /// Optional: Paging options + [ManualRoute("GET", "/user/packages/{package_type}/{package_name}/versions")] + public Task> GetAllForActiveUser(PackageType packageType, string packageName, PackageVersionState state = PackageVersionState.Active, ApiOptions options = null) + { + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.ApiOptionsNotNull(ref options); + + var route = ApiUrls.PackageVersionsActiveUser(packageType, packageName); + var parameters = ParameterBuilder.AddParameter("state", state); + + return ApiConnection.GetAll(route, parameters, options); + } + + /// + /// Gets a specific package version for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + [ManualRoute("GET", "/user/packages/{package_type}/{package_name}/versions/{package_version_id}")] + public Task GetForActiveUser(PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + var route = ApiUrls.PackageVersionActiveUser( packageType, packageName, packageVersionId); + + return ApiConnection.Get(route); + } + + /// + /// Deletes a specific package version for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + [ManualRoute("DELETE", "/user/packages/{package_type}/{package_name}/versions/{package_version_id}")] + public Task DeleteForActiveUser(PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + var route = ApiUrls.PackageVersionActiveUser(packageType, packageName, packageVersionId); + return ApiConnection.Delete(route); + } + + /// + /// Restores a package version owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + [ManualRoute("POST", "/user/packages/{package_type}/{package_name}/versions/{package_version_id}/restore")] + public Task RestoreForActiveUser(PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + var route = ApiUrls.PackageVersionRestoreActiveUser(packageType, packageName, packageVersionId); + + return ApiConnection.Post(route); + } + #endregion + + #region Specific User + /// + /// Returns all package versions for a public package owned by a specified user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Optional: Return packages with a state. Defaults to Active + /// Optional: Paging options + [ManualRoute("GET", "/users/{username}/packages/{package_type}/{package_name}/versions")] + public Task> GetAllForUser(string username, PackageType packageType, string packageName, PackageVersionState state = PackageVersionState.Active, ApiOptions options = null) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.ApiOptionsNotNull(ref options); + + var route = ApiUrls.PackageVersionsUser(username, packageType, packageName); + var parameters = ParameterBuilder.AddParameter("state", state); + + return ApiConnection.GetAll(route, parameters, options); + } + + /// + /// Gets a specific package version for a public package owned by a specified user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + [ManualRoute("GET", "/users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}")] + public Task GetForUser(string username, PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + var route = ApiUrls.PackageVersionUser(username, packageType, packageName, packageVersionId); + + return ApiConnection.Get(route); + } + + /// + /// Deletes a specific package version for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + [ManualRoute("DELETE", "/users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}")] + public Task DeleteForUser(string username, PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNull(packageType, nameof(packageType)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + var route = ApiUrls.PackageVersionUser(username, packageType, packageName, packageVersionId); + return ApiConnection.Delete(route); + } + + /// + /// Restores a specific package version for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + /// Required: The id of the package version + [ManualRoute("POST", "/users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore")] + public Task RestoreForUser(string username, PackageType packageType, string packageName, int packageVersionId) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + Ensure.GreaterThanZero(packageVersionId, nameof(packageVersionId)); + + var route = ApiUrls.PackageVersionRestoreUser(username, packageType, packageName, packageVersionId); + + return ApiConnection.Post(route); + } + #endregion + } +} diff --git a/Octokit/Clients/PackagesClient.cs b/Octokit/Clients/PackagesClient.cs new file mode 100644 index 00000000..d5de960f --- /dev/null +++ b/Octokit/Clients/PackagesClient.cs @@ -0,0 +1,258 @@ +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Octokit +{ + /// + /// A client for GitHub's Packages API. + /// + /// + /// See the Packages API documentation for more details. + /// + public class PackagesClient : ApiClient, IPackagesClient + { + public PackagesClient(IApiConnection apiConnection) : base(apiConnection) + { + PackageVersions = new PackageVersionsClient(apiConnection); + } + + public IPackageVersionsClient PackageVersions { get; private set; } + + #region Organization + /// + /// List all packages for an organisations, readable by the current user + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Optional: The visibility of the package + [ManualRoute("GET", "/orgs/{org}/packages")] + public Task> GetAllForOrg(string org, PackageType packageType, PackageVisibility? packageVisibility = null) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + + var route = ApiUrls.PackagesOrg(org); + var parameters = ParameterBuilder.AddParameter("package_type", packageType).AddOptionalParameter("visibility", packageVisibility); + + return ApiConnection.GetAll(route, parameters); + } + + /// + /// Get a specific package for an Organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + [ManualRoute("GET", "/orgs/{org}/packages/{package_type}/{package_name}")] + public Task GetForOrg(string org, PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + var route = ApiUrls.PackageOrg(org, packageType, packageName); + + return ApiConnection.Get(route); + } + + /// + /// Delete a specific package for an Organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + [ManualRoute("DELETE", "/orgs/{org}/packages/{package_type}/{package_name}")] + public Task DeleteForOrg(string org, PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + var route = ApiUrls.PackageOrg(org, packageType, packageName); + + return ApiConnection.Delete(route); + } + + /// + /// Restore a specific package for an Organization. + /// + /// + /// See the API documentation for more details + /// + /// Required: Organisation Name + /// Required: The type of package + /// Required: The name of the package + [ManualRoute("POST", "/orgs/{org}/packages/{package_type}/{package_name}/restore")] + public Task RestoreForOrg(string org, PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(org, nameof(org)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + var route = ApiUrls.PackageRestoreOrg(org, packageType, packageName); + + return ApiConnection.Post(route); + } + #endregion + + #region Active User + /// + /// Lists packages owned by the authenticated user within the user's namespace + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Optional: The visibility of the package + [ManualRoute("GET", "/user/packages")] + public Task> GetAllForActiveUser(PackageType packageType, PackageVisibility? packageVisibility = null) + { + var route = ApiUrls.PackagesActiveUser(); + var parameters = ParameterBuilder.AddParameter("package_type", packageType).AddOptionalParameter("visibility", packageVisibility); + + return ApiConnection.GetAll(route, parameters); + } + + /// + /// Gets a specific package for a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + [ManualRoute("GET", "/user/packages/{package_type}/{package_name}")] + public Task GetForActiveUser(PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + var route = ApiUrls.PackageActiveUser(packageType, packageName); + + return ApiConnection.Get(route); + } + + /// + /// Deletes a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + [ManualRoute("DELETE", "/user/packages/{package_type}/{package_name}")] + public Task DeleteForActiveUser(PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + var route = ApiUrls.PackageActiveUser(packageType, packageName); + + return ApiConnection.Delete(route); + } + + /// + /// Restores a package owned by the authenticated user. + /// + /// + /// See the API documentation for more details + /// + /// Required: The type of package + /// Required: The name of the package + [ManualRoute("POST", "/user/packages/{package_type}/{package_name}/restore")] + public Task RestoreForActiveUser(PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + var route = ApiUrls.PackageRestoreActiveUser(packageType, packageName); + + return ApiConnection.Post(route); + } + #endregion + + #region Specific User + /// + /// Lists packages owned by the authenticated user within the user's namespace + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Optional: The visibility of the package + [ManualRoute("GET", "/users/{username}/packages")] + public Task> GetAllForUser(string username, PackageType packageType, PackageVisibility? packageVisibility = null) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + + var route = ApiUrls.PackagesUser(username); + var parameters = ParameterBuilder.AddParameter("package_type", packageType).AddOptionalParameter("visibility", packageVisibility); + + return ApiConnection.GetAll(route, parameters); + } + + /// + /// Gets a specific package metadata for a public package owned by a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + [ManualRoute("GET", "/users/{username}/packages/{package_type}/{package_name}")] + public Task GetForUser(string username, PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + var route = ApiUrls.PackageUser(username, packageType, packageName); + + return ApiConnection.Get(route); + } + + /// + /// Deletes an entire package for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + [ManualRoute("DELETE", "/users/{username}/packages/{package_type}/{package_name}")] + public Task DeleteForUser(string username, PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + var route = ApiUrls.PackageUser(username, packageType, packageName); + + return ApiConnection.Delete(route); + } + + /// + /// Restores an entire package for a user. + /// + /// + /// See the API documentation for more details + /// + /// Required: Username + /// Required: The type of package + /// Required: The name of the package + [ManualRoute("POST", "/users/{username}/packages/{package_type}/{package_name}/restore")] + public Task RestoreForUser(string username, PackageType packageType, string packageName) + { + Ensure.ArgumentNotNullOrEmptyString(username, nameof(username)); + Ensure.ArgumentNotNullOrEmptyString(packageName, nameof(packageName)); + + var route = ApiUrls.PackageRestoreUser(username, packageType, packageName); + + return ApiConnection.Post(route); + } + #endregion + } +} diff --git a/Octokit/GitHubClient.cs b/Octokit/GitHubClient.cs index f0305408..f3b2f0c0 100644 --- a/Octokit/GitHubClient.cs +++ b/Octokit/GitHubClient.cs @@ -111,6 +111,7 @@ namespace Octokit User = new UsersClient(apiConnection); Reaction = new ReactionsClient(apiConnection); Check = new ChecksClient(apiConnection); + Packages = new PackagesClient(apiConnection); } /// @@ -225,6 +226,14 @@ namespace Octokit /// public IOrganizationsClient Organization { get; private set; } + /// + /// Access GitHub's Pacakges API. + /// + /// + /// Refer to the API documentation for more information: https://docs.github.com/en/rest/packages + /// + public IPackagesClient Packages { get; private set; } + /// /// Access GitHub's Pull Requests API. /// diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index de890c62..86679989 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -4457,5 +4457,167 @@ namespace Octokit { return "meta".FormatUri(); } + + /// + /// Returns the for the Packages request + /// + /// The Packages endpoint. + public static Uri PackagesOrg(string org) + { + return "/orgs/{0}/packages".FormatUri(org); + } + + /// + /// Returns the for the Package request + /// + /// The Package endpoint. + public static Uri PackageOrg(string org, PackageType packageType, string packageName) + { + return "/orgs/{0}/packages/{1}/{2}".FormatUri(org, packageType.ToParameter(), packageName); + } + + /// + /// Returns the for the Package Restore request + /// + /// The Package Restore endpoint. + public static Uri PackageRestoreOrg(string org, PackageType packageType, string packageName) + { + return "/orgs/{0}/packages/{1}/{2}/restore".FormatUri(org, packageType.ToParameter(), packageName); + } + + /// + /// Returns the for the Package Versions request + /// + /// The Package endpoint. + public static Uri PackageVersionsOrg(string org, PackageType packageType, string packageName) + { + return "/orgs/{0}/packages/{1}/{2}/versions".FormatUri(org, packageType.ToParameter(), packageName); + } + + /// + /// Returns the for the Package Version request + /// + /// The Package endpoint. + public static Uri PackageVersionOrg(string org, PackageType packageType, string packageName, int packageVersionId) + { + return "/orgs/{0}/packages/{1}/{2}/versions/{3}".FormatUri(org, packageType.ToParameter(), packageName, packageVersionId); + } + + /// + /// Returns the for the Package Version request + /// + /// The Package endpoint. + public static Uri PackageVersionRestoreOrg(string org, PackageType packageType, string packageName, int packageVersionId) + { + return "/orgs/{0}/packages/{1}/{2}/versions/{3}/restore".FormatUri(org, packageType.ToParameter(), packageName, packageVersionId); + } + + /// + /// Returns the for the Packages request + /// + /// The Packages endpoint. + public static Uri PackagesActiveUser() + { + return "/user/packages".FormatUri(); + } + + /// + /// Returns the for the Package request + /// + /// The Package endpoint. + public static Uri PackageActiveUser(PackageType packageType, string packageName) + { + return "/user/packages/{0}/{1}".FormatUri(packageType.ToParameter(), packageName); + } + + /// + /// Returns the for the Package Restore request + /// + /// The Package Restore endpoint. + public static Uri PackageRestoreActiveUser(PackageType packageType, string packageName) + { + return "/user/packages/{0}/{1}/restore".FormatUri(packageType.ToParameter(), packageName); + } + + /// + /// Returns the for the Package Versions request + /// + /// The Package endpoint. + public static Uri PackageVersionsActiveUser(PackageType packageType, string packageName) + { + return "/user/packages/{0}/{1}/versions".FormatUri(packageType.ToParameter(), packageName); + } + + /// + /// Returns the for the Package Version request + /// + /// The Package endpoint. + public static Uri PackageVersionActiveUser(PackageType packageType, string packageName, int packageVersionId) + { + return "/user/packages/{0}/{1}/versions/{2}".FormatUri(packageType.ToParameter(), packageName, packageVersionId); + } + + /// + /// Returns the for the Package Version request + /// + /// The Package endpoint. + public static Uri PackageVersionRestoreActiveUser(PackageType packageType, string packageName, int packageVersionId) + { + return "/user/packages/{0}/{1}/versions/{2}/restore".FormatUri(packageType.ToParameter(), packageName, packageVersionId); + } + + /// + /// Returns the for the Packages request + /// + /// The Packages endpoint. + public static Uri PackagesUser(string username) + { + return "/users/{0}/packages".FormatUri(username); + } + + /// + /// Returns the for the Package request + /// + /// The Package endpoint. + public static Uri PackageUser(string username, PackageType packageType, string packageName) + { + return "/users/{0}/packages/{1}/{2}".FormatUri(username, packageType.ToParameter(), packageName); + } + + /// + /// Returns the for the Package Restore request + /// + /// The Package Restore endpoint. + public static Uri PackageRestoreUser(string username, PackageType packageType, string packageName) + { + return "/users/{0}/packages/{1}/{2}/restore".FormatUri(username, packageType.ToParameter(), packageName); + } + + /// + /// Returns the for the Package Versions request + /// + /// The Package endpoint. + public static Uri PackageVersionsUser(string username, PackageType packageType, string packageName) + { + return "/users/{0}/packages/{1}/{2}/versions".FormatUri(username, packageType.ToParameter(), packageName); + } + + /// + /// Returns the for the Package Version request + /// + /// The Package endpoint. + public static Uri PackageVersionUser(string username, PackageType packageType, string packageName, int packageVersionId) + { + return "/users/{0}/packages/{1}/{2}/versions/{3}".FormatUri(username, packageType.ToParameter(), packageName, packageVersionId); + } + + /// + /// Returns the for the Package Version request + /// + /// The Package endpoint. + public static Uri PackageVersionRestoreUser(string username, PackageType packageType, string packageName, int packageVersionId) + { + return "/users/{0}/packages/{1}/{2}/versions/{3}/restore".FormatUri(username, packageType.ToParameter(), packageName, packageVersionId); + } } } diff --git a/Octokit/Helpers/Ensure.cs b/Octokit/Helpers/Ensure.cs index 727c5422..77204d95 100644 --- a/Octokit/Helpers/Ensure.cs +++ b/Octokit/Helpers/Ensure.cs @@ -50,6 +50,20 @@ namespace Octokit throw new ArgumentException("Timespan must be greater than zero", name); } + /// + /// Checks an integer argument to ensure it is a positive value. + /// + /// The argument value to check + /// The name of the argument + public static void GreaterThanZero([ValidatedNotNull] int value, string name) + { + ArgumentNotNull(value, name); + + if (value > 0) return; + + throw new ArgumentException("Value must be greater than zero", name); + } + /// /// Checks an enumerable argument to ensure it isn't null or empty. /// @@ -62,6 +76,11 @@ namespace Octokit throw new ArgumentException("List cannot be empty", name); } + + public static void ApiOptionsNotNull(ref ApiOptions options) + { + options = options ?? ApiOptions.None; + } } [AttributeUsage(AttributeTargets.Parameter)] diff --git a/Octokit/Helpers/EnumExtensions.cs b/Octokit/Helpers/EnumExtensions.cs index 83bb3fae..3eae11a8 100644 --- a/Octokit/Helpers/EnumExtensions.cs +++ b/Octokit/Helpers/EnumExtensions.cs @@ -24,5 +24,21 @@ namespace Octokit return attribute != null ? attribute.Value : propString.ToLowerInvariant(); } + + internal static bool HasParameter(this Enum prop) + { + if (prop == null) return false; + + var propString = prop.ToString(); + var member = prop.GetType().GetMember(propString).FirstOrDefault(); + + if (member == null) return false; + + var attribute = member.GetCustomAttributes(typeof(ParameterAttribute), false) + .Cast() + .FirstOrDefault(); + + return attribute != null; + } } } diff --git a/Octokit/Helpers/ParameterBuilder.cs b/Octokit/Helpers/ParameterBuilder.cs new file mode 100644 index 00000000..56bb0745 --- /dev/null +++ b/Octokit/Helpers/ParameterBuilder.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; + +namespace Octokit +{ + public static class ParameterBuilder + { + public static Dictionary AddParameter(string key, string value) + { + Ensure.ArgumentNotNullOrEmptyString(key, nameof(key)); + Ensure.ArgumentNotNullOrEmptyString(value, nameof(value)); + + return new Dictionary { { key, value } }; + } + + public static Dictionary AddParameter(string key, Enum value) + { + Ensure.ArgumentNotNullOrEmptyString(key, nameof(key)); + Ensure.ArgumentNotNull(value, nameof(value)); + + if (value.HasParameter()) + { + return new Dictionary { { key, value.ToParameter() } }; + } + + return new Dictionary { { key, value.ToString() } }; + + } + + public static Dictionary AddParameter(this Dictionary data, string key, string value) + { + Ensure.ArgumentNotNull(data, nameof(data)); + Ensure.ArgumentNotNullOrEmptyString(key, nameof(key)); + Ensure.ArgumentNotNullOrEmptyString(value, nameof(value)); + + data.Add(key, value); + return data; + } + + public static Dictionary AddParameter(this Dictionary data, string key, Enum value) + { + Ensure.ArgumentNotNull(data, nameof(data)); + Ensure.ArgumentNotNullOrEmptyString(key, nameof(key)); + Ensure.ArgumentNotNull(value, nameof(value)); + + if (value.HasParameter()) + { + data.Add(key, value.ToParameter()); + } + else + { + data.Add(key, value.ToString()); + } + + return data; + } + + + public static Dictionary AddOptionalParameter(this Dictionary data, string key, string value) + { + Ensure.ArgumentNotNull(data, nameof(data)); + Ensure.ArgumentNotNullOrEmptyString(key, nameof(key)); + + if (value != null) + { + data.Add(key, value); + } + return data; + } + + public static Dictionary AddOptionalParameter(this Dictionary data, string key, Enum value) + { + Ensure.ArgumentNotNull(data, nameof(data)); + Ensure.ArgumentNotNullOrEmptyString(key, nameof(key)); + + if (value != null) + { + if (value.HasParameter()) + { + data.Add(key, value.ToParameter()); + } + else + { + data.Add(key, value.ToString()); + } + } + + return data; + } + } +} diff --git a/Octokit/IGitHubClient.cs b/Octokit/IGitHubClient.cs index 43b01793..0d2ee952 100644 --- a/Octokit/IGitHubClient.cs +++ b/Octokit/IGitHubClient.cs @@ -87,6 +87,14 @@ namespace Octokit /// IOrganizationsClient Organization { get; } + /// + /// Access GitHub's Pacakges API. + /// + /// + /// Refer to the API documentation for more information: https://docs.github.com/en/rest/packages + /// + IPackagesClient Packages { get; } + /// /// Access GitHub's Pull Requests API. /// diff --git a/Octokit/Models/Common/PackageType.cs b/Octokit/Models/Common/PackageType.cs new file mode 100644 index 00000000..7d9201dc --- /dev/null +++ b/Octokit/Models/Common/PackageType.cs @@ -0,0 +1,43 @@ +using Octokit.Internal; + +namespace Octokit +{ + public enum PackageType + { + /// + /// Npm repository packages + /// + [Parameter(Value = "npm")] + Npm, + + /// + /// Gradle registry packages + /// + [Parameter(Value = "maven")] + Maven, + + /// + /// RubyGems packages + /// + [Parameter(Value = "rubygems")] + RubyGems, + + /// + /// Docker container registry packages + /// + [Parameter(Value = "docker")] + Docker, + + /// + /// Nuget registry packages + /// + [Parameter(Value = "nuget")] + Nuget, + + /// + /// Container registry packages + /// + [Parameter(Value = "container")] + Container, + } +} diff --git a/Octokit/Models/Common/PackageVersionState.cs b/Octokit/Models/Common/PackageVersionState.cs new file mode 100644 index 00000000..fc90f32c --- /dev/null +++ b/Octokit/Models/Common/PackageVersionState.cs @@ -0,0 +1,19 @@ +using Octokit.Internal; + +namespace Octokit +{ + public enum PackageVersionState + { + /// + /// Package version which is active + /// + [Parameter(Value = "active")] + Active, + + /// + /// Package version whic is deleted + /// + [Parameter(Value = "deleted")] + Deleted + } +} diff --git a/Octokit/Models/Common/PackageVisibility.cs b/Octokit/Models/Common/PackageVisibility.cs new file mode 100644 index 00000000..360d4939 --- /dev/null +++ b/Octokit/Models/Common/PackageVisibility.cs @@ -0,0 +1,25 @@ +using Octokit.Internal; + +namespace Octokit +{ + public enum PackageVisibility + { + /// + /// Only public packages + /// + [Parameter(Value = "public")] + Public, + + /// + /// Only private packages + /// + [Parameter(Value = "private")] + Private, + + /// + /// Only supported by container package types, otherwise the same as private + /// + [Parameter(Value = "internal")] + Internal + } +} diff --git a/Octokit/Models/Response/Package.cs b/Octokit/Models/Response/Package.cs new file mode 100644 index 00000000..b8adedf2 --- /dev/null +++ b/Octokit/Models/Response/Package.cs @@ -0,0 +1,78 @@ +using Octokit.Internal; +using System; +using System.Diagnostics; + +namespace Octokit +{ + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class Package + { + public Package() { } + + public Package(long id, string name, PackageType packageType, Author owner, int versionCount, PackageVisibility visibility, string url, DateTime createdAt, DateTime updatedAt, string htmlUrl) + { + Id = id; + Name = name; + PackageType = packageType; + Owner = owner; + VersionCount = versionCount; + Visibility = visibility; + Url = url; + CreatedAt = createdAt; + UpdatedAt = updatedAt; + HtmlUrl = htmlUrl; + } + + /// + /// The Id of the package + /// + public long Id { get; private set; } + + /// + /// The Name of the package + /// + public string Name { get; private set; } + + /// + /// The Type of the package + /// + public StringEnum PackageType { get; private set; } + + /// + /// The Owner of the package + /// + public Author Owner { get; private set; } + + /// + /// The Version Count of the package + /// + public int VersionCount { get; private set; } + + /// + /// The Visibility of the package + /// + public StringEnum Visibility { get; private set; } + + /// + /// The Url of the package + /// + public string Url { get; private set; } + + /// + /// The Date the package was first created + /// + public DateTime CreatedAt { get; private set; } + + /// + /// The Date the package was last updated + /// + public DateTime UpdatedAt { get; private set; } + + /// + /// The Url of the package + /// + public string HtmlUrl { get; private set; } + + internal string DebuggerDisplay => new SimpleJsonSerializer().Serialize(this); + } +} \ No newline at end of file diff --git a/Octokit/Models/Response/PackageVersion.cs b/Octokit/Models/Response/PackageVersion.cs new file mode 100644 index 00000000..b1c918d0 --- /dev/null +++ b/Octokit/Models/Response/PackageVersion.cs @@ -0,0 +1,73 @@ +using Octokit.Internal; +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Octokit +{ + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class PackageVersion + { + public PackageVersion() { } + + public PackageVersion(long id, string name, string url, string packageHtmlUrl, DateTime createdAt, DateTime updatedAt, string htmlUrl, PackageVersionMetadata metadata) + { + Id = id; + Name = name; + Url = url; + PackageHtmlUrl = packageHtmlUrl; + CreatedAt = createdAt; + UpdatedAt = updatedAt; + HtmlUrl = htmlUrl; + Metadata = metadata; + } + + public long Id { get; private set; } + + public string Name { get; private set; } + + public string Url { get; private set; } + + public string PackageHtmlUrl { get; private set; } + + public DateTime CreatedAt { get; private set; } + + public DateTime UpdatedAt { get; private set; } + + public string HtmlUrl { get; private set; } + + public PackageVersionMetadata Metadata { get; private set; } + + internal string DebuggerDisplay => new SimpleJsonSerializer().Serialize(this); + } + + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class PackageVersionMetadata + { + public PackageVersionMetadata() { } + + public PackageVersionMetadata(string packageType) + { + PackageType = packageType; + } + + public string PackageType { get; private set; } + + internal string DebuggerDisplay => new SimpleJsonSerializer().Serialize(this); + } + + [DebuggerDisplay("{DebuggerDisplay,nq}")] + public class PackageVersionMetadataContainer + { + public PackageVersionMetadataContainer() { } + + public PackageVersionMetadataContainer(IReadOnlyList tags) + { + Tags = tags; + } + + public IReadOnlyList Tags { get; private set; } + + internal string DebuggerDisplay => new SimpleJsonSerializer().Serialize(this); + } +} \ No newline at end of file