From 103d1c64f133b57e052f62043406dfa84910a037 Mon Sep 17 00:00:00 2001 From: Stephan Vock Date: Fri, 22 Nov 2024 16:08:38 +0000 Subject: [PATCH 1/3] Adjust README to use suborganization instead of subrepository --- README.md | 251 +++++++++++++++++++++++++++--------------------------- 1 file changed, 126 insertions(+), 125 deletions(-) diff --git a/README.md b/README.md index e2bc0b7..92a6858 100644 --- a/README.md +++ b/README.md @@ -53,36 +53,36 @@ * [List packages in a vendor bundle](#list-packages-in-a-vendor-bundle) * [Add one or more packages to a vendor bundle or edit their limitations](#add-one-or-more-packages-to-a-vendor-bundle-or-edit-their-limitations) * [Remove a package from a vendor bundle](#remove-a-package-from-a-vendor-bundle) - * [Subrepository](#subrepository) - * [List an organization's subrepositories](#list-an-organizations-subrepositories) - * [Show a subrepository](#show-a-subrepository) - * [Create a subrepository](#create-a-subrepository) - * [Delete a subrepository](#delete-a-subrepository) - * [List a subrepository's teams](#list-a-subrepositorys-teams) - * [Add a team to a subrepository or edit the permission](#add-a-team-to-a-subrepository-or-edit-the-permission) - * [Remove a team from a subrepository](#remove-a-team-from-a-subrepository) - * [List a subrepository's packages](#list-a-subrepositorys-packages) - * [Show a subrepository package](#show-a-subrepository-package) - * [Create a vcs package in a subrepository](#create-a-vcs-package-in-a-subrepository) - * [Create a vcs package with credentials in a subrepository](#create-a-vcs-package-with-credentials-in-a-subrepository) - * [Create a custom package in a subrepository](#create-a-custom-package-in-a-subrepository) - * [Create a custom package with credentials in a subrepository](#create-a-custom-package-with-credentials-in-a-subrepository) - * [Edit a vcs package in a subrepository in a subrepository](#edit-a-vcs-package-in-a-subrepository-in-a-subrepository) - * [Edit a custom package in a subrepository](#edit-a-custom-package-in-a-subrepository) - * [Delete a package from a subrepository](#delete-a-package-from-a-subrepository) - * [List all dependents of a subrepository package](#list-all-dependents-of-a-subrepository-package) - * [List a subrepository's authentication tokens](#list-a-subrepositorys-authentication-tokens) - * [Create a subrepository authentication token](#create-a-subrepository-authentication-token) - * [Delete a subrepository authentication token](#delete-a-subrepository-authentication-token) - * [Regenerate a subrepository authentication token](#regenerate-a-subrepository-authentication-token) - * [List a subrepository's mirrored repositories](#list-a-subrepositorys-mirrored-repositories) + * [Suborganization](#suborganization) + * [List an organization's suborganizations](#list-an-organizations-suborganizations) + * [Show a suborganization](#show-a-suborganization) + * [Create a suborganization](#create-a-suborganization) + * [Delete a suborganization](#delete-a-suborganization) + * [List a suborganization's teams](#list-a-suborganizations-teams) + * [Add a team to a suborganization or edit the permission](#add-a-team-to-a-suborganization-or-edit-the-permission) + * [Remove a team from a suborganization](#remove-a-team-from-a-suborganization) + * [List a suborganization's packages](#list-a-suborganizations-packages) + * [Show a suborganization package](#show-a-suborganization-package) + * [Create a vcs package in a suborganization](#create-a-vcs-package-in-a-suborganization) + * [Create a vcs package with credentials in a suborganization](#create-a-vcs-package-with-credentials-in-a-suborganization) + * [Create a custom package in a suborganization](#create-a-custom-package-in-a-suborganization) + * [Create a custom package with credentials in a suborganization](#create-a-custom-package-with-credentials-in-a-suborganization) + * [Edit a vcs package in a suborganization in a suborganization](#edit-a-vcs-package-in-a-suborganization-in-a-suborganization) + * [Edit a custom package in a suborganization](#edit-a-custom-package-in-a-suborganization) + * [Delete a package from a suborganization](#delete-a-package-from-a-suborganization) + * [List all dependents of a suborganization package](#list-all-dependents-of-a-suborganization-package) + * [List a suborganization's authentication tokens](#list-a-suborganizations-authentication-tokens) + * [Create a suborganization authentication token](#create-a-suborganization-authentication-token) + * [Delete a suborganization authentication token](#delete-a-suborganization-authentication-token) + * [Regenerate a suborganization authentication token](#regenerate-a-suborganization-authentication-token) + * [List a suborganization's mirrored repositories](#list-a-suborganizations-mirrored-repositories) * [Show a mirrored repository](#show-a-mirrored-repository) - * [Add mirrored repositories to a subrepository](#add-mirrored-repositories-to-a-subrepository) - * [Edit the mirroring behaviour of mirrored repository in a subrepository](#edit-the-mirroring-behaviour-of-mirrored-repository-in-a-subrepository) - * [Delete a mirrored repository from a subrepository](#delete-a-mirrored-repository-from-a-subrepository) - * [List all mirrored packages from a mirrored repository in a subrepository](#list-all-mirrored-packages-from-a-mirrored-repository-in-a-subrepository) - * [Add mirrored packages from one mirrored repository to a subrepository](#add-mirrored-packages-from-one-mirrored-repository-to-a-subrepository) - * [Remove all mirrored packages from one mirrored repository in a subrepository](#remove-all-mirrored-packages-from-one-mirrored-repository-in-a-subrepository) + * [Add mirrored repositories to a suborganization](#add-mirrored-repositories-to-a-suborganization) + * [Edit the mirroring behaviour of mirrored repository in a suborganization](#edit-the-mirroring-behaviour-of-mirrored-repository-in-a-suborganization) + * [Delete a mirrored repository from a suborganization](#delete-a-mirrored-repository-from-a-suborganization) + * [List all mirrored packages from a mirrored repository in a suborganization](#list-all-mirrored-packages-from-a-mirrored-repository-in-a-suborganization) + * [Add mirrored packages from one mirrored repository to a suborganization](#add-mirrored-packages-from-one-mirrored-repository-to-a-suborganization) + * [Remove all mirrored packages from one mirrored repository in a suborganization](#remove-all-mirrored-packages-from-one-mirrored-repository-in-a-suborganization) * [Package](#package) * [List an organization's packages](#list-an-organizations-packages) * [Show a package](#show-a-package) @@ -131,7 +131,7 @@ * [License](#license) - + @@ -182,7 +182,7 @@ Returns an array of created jobs. One for every synchronization. The permissions available for a team are: - `canEditTeamPackages`: members of the team can edit and remove packages, assign package permissions (only applies to packages assigned to team). - `canAddPackages`: members of the team can add packages to organization; add, edit and remove credentials and mirrored third-party repositories. -- `canCreateSubrepositories`: members of the team can create subrepositories. +- `canCreateSuborganizations`: members of the team can create suborganizations. - `canViewVendorCustomers`: members of the team can view customers, their Composer information, their packages, and their install statistics. - `canManageVendorCustomers`: members of the team can create and delete customers, add and remove packages, update their settings, view Composer information and install statistics. @@ -193,7 +193,7 @@ $permissions = new TeamPermissions; // Grant all permissions. $permissions->canEditTeamPackages = true; $permissions->canAddPackages = true; -$permissions->canCreateSubrepositories = true; +$permissions->canCreateSuborganizations = true; $permissions->canManageVendorCustomers = true; $permissions->canManageVendorCustomers = true; ``` @@ -551,241 +551,242 @@ $packageName = 'acme-website/package'; $client->vendorBundles()->packages()->removePackage($vendorBundleId, $packageName); ``` -### Subrepository +### Suborganization -#### List an organization's subrepositories +#### List an organization's suborganizations ```php -$subrepositories = $client->subrepositories()->all(); +$suborganizations = $client->suborganizations()->all(); ``` -Returns an array of subrepositories. +Returns an array of suborganizations. -#### Show a subrepository +#### Show a suborganization ```php -$subrepositoryName = 'subrepository'; -$subrepository = $client->subrepositories()->show($subrepositoryName); +$suborganizationName = 'suborganization'; +$suborganization = $client->suborganizations()->show($suborganizationName); ``` -Returns a single subrepository. +Returns a single suborganization. -#### Create a subrepository +#### Create a suborganization ```php -$subrepository = $client->subrepositories()->create('New subrepository name'); +$suborganization = $client->subrepositories()->create('New suborganization name'); ``` -Returns the subrepository. +Returns the suborganization. -#### Delete a subrepository +#### Delete a suborganization ```php -$subrepositoryName = 'subrepository'; -$client->subrepositories()->remove($subrepositoryName); +$suborganizationName = 'suborganization'; +$client->suborganizations()->remove($suborganizationName); ``` -#### List a subrepository's teams +#### List a suborganization's teams ```php -$subrepositoryName = 'subrepository'; -$teams = $client->subrepositories()->listTeams($subrepositoryName); +$suborganizationName = 'suborganization'; +$teams = $client->suborganizations()->listTeams($suborganizationName); ``` -Returns an array of subrepositories teams. +Returns an array of suborganizations teams. -#### Add a team to a subrepository or edit the permission +#### Add a team to a suborganization or edit the permission ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $teams = [ [ 'id' => 12, 'permission' => 'owner', ], ]; -$teams = $client->subrepositories()->addOrEditTeams($subrepositoryName, $teams); +$teams = $client->suborganizations()->addOrEditTeams($suborganizationName, $teams); ``` -Returns an array of added subrepository teams. +Returns an array of added suborganization teams. -#### Remove a team from a subrepository +#### Remove a team from a suborganization ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $teamId = 12; -$client->subrepositories()->removeTeam($subrepositoryName, $teamId); +$client->suborganizations()->removeTeam($suborganizationName, $teamId); ``` -#### List a subrepository's packages +#### List a suborganization's packages ```php -$subrepositoryName = 'subrepository'; -$packages = $client->subrepositories()->packages()->all($subrepositoryName); +$suborganizationName = 'suborganization'; +$packages = $client->suborganizations()->packages()->all($suborganizationName); ``` -Returns an array of subrepositories packages. +Returns an array of suborganizations packages. -#### Show a subrepository package +#### Show a suborganization package You can reference a package by its name or ID. ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; // Either use package name: -$package = $client->subrepositories()->packages()->show($subrepositoryName, 'acme-website/package'); +$package = $client->suborganizations()->packages()->show($suborganizationName, 'acme-website/package'); // Or the package ID: -$package = $client->subrepositories()->packages()->show($subrepositoryName, 123); +$package = $client->suborganizations()->packages()->show($suborganizationName, 123); ``` Returns the package. -#### Create a vcs package in a subrepository +#### Create a vcs package in a suborganization ```php -$subrepositoryName = 'subrepository'; -$job = $client->subrepositories()->packages()->createVcsPackage($subrepositoryName, 'https://github.com/acme-website/package'); +$suborganizationName = 'suborganization'; +$job = $client->suborganizations()->packages()->createVcsPackage($suborganizationName, 'https://github.com/acme-website/package'); ``` Returns a new job. -#### Create a vcs package with credentials in a subrepository +#### Create a vcs package with credentials in a suborganization ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $credentialId = 42; -$job = $client->subrepositories()->packages()->createVcsPackage($subrepositoryName,'https://github.com/acme-website/package', $credentialId); +$job = $client->suborganizations()->packages()->createVcsPackage($suborganizationName,'https://github.com/acme-website/package', $credentialId); ``` Returns a new job. -#### Create a custom package in a subrepository +#### Create a custom package in a suborganization + ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $packageDefinition = '{...}'; -$job = $client->subrepositories()->packages()->createCustomPackage($subrepositoryName, $packageDefinition); +$job = $client->suborganizations()->packages()->createCustomPackage($suborganizationName, $packageDefinition); ``` Returns a new job. -#### Create a custom package with credentials in a subrepository +#### Create a custom package with credentials in a suborganization ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $packageDefinition = '{...}'; $credentialId = 42; -$job = $client->subrepositories()->packages()->createCustomPackage($subrepositoryName, $packageDefinition, $credentialId); +$job = $client->suborganizations()->packages()->createCustomPackage($suborganizationName, $packageDefinition, $credentialId); ``` Returns a new job. -#### Edit a vcs package in a subrepository in a subrepository +#### Edit a vcs package in a suborganization in a suborganization ```php -$subrepositoryName = 'subrepository'; -$job = $client->subrepositories()->packages()->editVcsPackage($subrepositoryName, 'acme-website/package', 'https://github.com/acme-website/package'); +$suborganizationName = 'suborganization'; +$job = $client->suborganizations()->packages()->editVcsPackage($suborganizationName, 'acme-website/package', 'https://github.com/acme-website/package'); ``` Returns a new job. -#### Edit a custom package in a subrepository +#### Edit a custom package in a suborganization ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $packageDefinition = '{...}'; -$job = $client->subrepositories()->packages()->editCustomPackage($subrepositoryName, 'acme-website/package', $packageDefinition); +$job = $client->suborganizations()->packages()->editCustomPackage($suborganizationName, 'acme-website/package', $packageDefinition); ``` Returns a new job. -#### Delete a package from a subrepository +#### Delete a package from a suborganization ```php -$subrepositoryName = 'subrepository'; -$client->subrepositories()->packages()->remove($subrepositoryName, 'acme-website/package'); +$suborganizationName = 'suborganization'; +$client->suborganizations()->packages()->remove($suborganizationName, 'acme-website/package'); ``` -#### List all dependents of a subrepository package +#### List all dependents of a suborganization package ```php -$subrepositoryName = 'subrepository'; -$client->subrepositories()->packages()->listDependents($subrepositoryName, 'acme-website/package'); +$suborganizationName = 'suborganization'; +$client->suborganizations()->packages()->listDependents($suborganizationName, 'acme-website/package'); ``` Returns a list of packages. -#### List a subrepository's authentication tokens +#### List a suborganization's authentication tokens ```php -$subrepositoryName = 'subrepository'; -$tokens = $client->subrepositories()->listTokens($subrepositoryName); +$suborganizationName = 'suborganization'; +$tokens = $client->suborganizations()->listTokens($suborganizationName); ``` Returns an array of authentication tokens. -#### Create a subrepository authentication token +#### Create a suborganization authentication token ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $data = [ - 'description' => 'Subrepository Token', + 'description' => 'Suborganization Token', 'access' => 'read', ]; -$token = $client->subrepositories()->createToken($subrepositoryName, $data); +$token = $client->suborganizations()->createToken($suborganizationName, $data); ``` Returns the authentication token. -#### Delete a subrepository authentication token +#### Delete a suborganization authentication token ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $tokenId = 33; -$client->subrepositories()->removeToken($subrepositoryName, $tokenId); +$client->suborganizations()->removeToken($suborganizationName, $tokenId); ``` -#### Regenerate a subrepository authentication token +#### Regenerate a suborganization authentication token ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $tokenId = 33; $confirmation = [ 'IConfirmOldTokenWillStopWorkingImmediately' => true, ]; -$token = $client->subrepositories()->regenerateToken($subrepositoryName, $confirmation); +$token = $client->suborganizations()->regenerateToken($suborganizationName, $confirmation); ``` Returns the authentication token. -#### List a subrepository's mirrored repositories +#### List a suborganization's mirrored repositories ```php -$subrepositoryName = 'subrepository'; -$mirroredRepositories = $client->subrepositories()->mirroredRepositories()->all($subrepositoryName); +$suborganizationName = 'suborganization'; +$mirroredRepositories = $client->suborganizations()->mirroredRepositories()->all($suborganizationName); ``` Returns an array of mirrored repositories. #### Show a mirrored repository ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $mirroredRepositoryId = 42; -$mirroredRepository = $client->subrepositories()->mirroredRepositories()->show($subrepositoryName, $mirroredRepositoryId); +$mirroredRepository = $client->suborganizations()->mirroredRepositories()->show($suborganizationName, $mirroredRepositoryId); ``` Returns the mirrored repository. -#### Add mirrored repositories to a subrepository +#### Add mirrored repositories to a suborganization ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $mirroredRepositoriesToAdd = [ ['id' => 12, 'mirroringBehavior' => 'add_on_use'], ]; -$mirroredRepository = $client->subrepositories()->mirroredRepositories()->add($subrepositoryName, $mirroredRepositoriesToAdd); +$mirroredRepository = $client->suborganizations()->mirroredRepositories()->add($suborganizationName, $mirroredRepositoriesToAdd); ``` Returns a list of added mirrored repositories. -#### Edit the mirroring behaviour of mirrored repository in a subrepository +#### Edit the mirroring behaviour of mirrored repository in a suborganization ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $mirroredRepositoryId = 42; -$mirroredRepository = $client->subrepositories()->mirroredRepositories()->create($subrepositoryName, $mirroredRepositoryId, 'add_on_use'); +$mirroredRepository = $client->suborganizations()->mirroredRepositories()->create($suborganizationName, $mirroredRepositoryId, 'add_on_use'); ``` Returns the edited mirrored repository. -#### Delete a mirrored repository from a subrepository +#### Delete a mirrored repository from a suborganization ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $mirroredRepositoryId = 42; -$client->subrepositories()->mirroredRepositories()->remove($subrepositoryName, $mirroredRepositoryId); +$client->suborganizations()->mirroredRepositories()->remove($suborganizationName, $mirroredRepositoryId); ``` -#### List all mirrored packages from a mirrored repository in a subrepository +#### List all mirrored packages from a mirrored repository in a suborganization ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $mirroredRepositoryId = 42; -$packages = $client->subrepositories()->mirroredRepositories()->listPackages($subrepositoryName, $mirroredRepositoryId); +$packages = $client->suborganizations()->mirroredRepositories()->listPackages($suborganizationName, $mirroredRepositoryId); ``` Returns an array of packages. -#### Add mirrored packages from one mirrored repository to a subrepository +#### Add mirrored packages from one mirrored repository to a suborganization ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $mirroredRepositoryId = 42; $packages = [ 'acme/cool-lib ]; -$jobs = $client->subrepositories()->mirroredRepositories()->addPackages($subrepositoryName, $mirroredRepositoryId, $packages); +$jobs = $client->suborganizations()->mirroredRepositories()->addPackages($suborganizationName, $mirroredRepositoryId, $packages); ``` Returns an array of jobs. -#### Remove all mirrored packages from one mirrored repository in a subrepository +#### Remove all mirrored packages from one mirrored repository in a suborganization ```php -$subrepositoryName = 'subrepository'; +$suborganizationName = 'suborganization'; $mirroredRepositoryId = 42; -$client->subrepositories()->mirroredRepositories()->removePackages($subrepositoryName, $mirroredRepositoryId); +$client->suborganizations()->mirroredRepositories()->removePackages($suborganizationName, $mirroredRepositoryId); ``` ### Package From fbb054b2b9fc0f3b11bf34900ac7aaf90d6fc1f9 Mon Sep 17 00:00:00 2001 From: Stephan Vock Date: Tue, 10 Dec 2024 10:39:20 +0000 Subject: [PATCH 2/3] Suborganizations: deprecate subrepository usage and add subroganization endpoints --- src/Api/Projects.php | 2 +- src/Api/Projects/MirroredRepositories.php | 2 +- src/Api/Projects/Packages.php | 2 +- src/Api/Suborganizations.php | 94 +++++++ .../Suborganizations/MirroredRepositories.php | 64 +++++ src/Api/Suborganizations/Packages.php | 70 +++++ src/Api/Subrepositories.php | 3 + .../Subrepositories/MirroredRepositories.php | 3 + src/Api/Subrepositories/Packages.php | 3 + src/Api/Teams.php | 4 +- src/Client.php | 13 +- src/TeamPermissions.php | 17 +- .../MirroredRepositoriesTest.php | 170 ++++++++++++ tests/Api/Suborganizations/PackagesTest.php | 220 ++++++++++++++++ tests/Api/SuborganizationsTest.php | 243 ++++++++++++++++++ tests/Api/TeamsTest.php | 14 +- 16 files changed, 907 insertions(+), 17 deletions(-) create mode 100644 src/Api/Suborganizations.php create mode 100644 src/Api/Suborganizations/MirroredRepositories.php create mode 100644 src/Api/Suborganizations/Packages.php create mode 100644 tests/Api/Suborganizations/MirroredRepositoriesTest.php create mode 100644 tests/Api/Suborganizations/PackagesTest.php create mode 100644 tests/Api/SuborganizationsTest.php diff --git a/src/Api/Projects.php b/src/Api/Projects.php index ee755bc..9b279db 100644 --- a/src/Api/Projects.php +++ b/src/Api/Projects.php @@ -10,7 +10,7 @@ namespace PrivatePackagist\ApiClient\Api; /** - * @deprecated Use the Subrepositories API instead + * @deprecated Use the Suborganizations API instead */ class Projects extends Subrepositories { diff --git a/src/Api/Projects/MirroredRepositories.php b/src/Api/Projects/MirroredRepositories.php index f455efd..fc95024 100644 --- a/src/Api/Projects/MirroredRepositories.php +++ b/src/Api/Projects/MirroredRepositories.php @@ -10,7 +10,7 @@ namespace PrivatePackagist\ApiClient\Api\Projects; /** - * @deprecated Use Subrepositories\MirroredRepositories instead + * @deprecated Use \PrivatePackagist\ApiClient\Api\Suborganizations\MirroredRepositories instead */ class MirroredRepositories extends \PrivatePackagist\ApiClient\Api\Subrepositories\MirroredRepositories { diff --git a/src/Api/Projects/Packages.php b/src/Api/Projects/Packages.php index 70aeaf3..cae72fc 100644 --- a/src/Api/Projects/Packages.php +++ b/src/Api/Projects/Packages.php @@ -10,7 +10,7 @@ namespace PrivatePackagist\ApiClient\Api\Projects; /** - * @deprecated Use Subrepositories\Packages instead + * @deprecated Use \PrivatePackagist\ApiClient\Api\Suborganizations\Packages instead */ class Packages extends \PrivatePackagist\ApiClient\Api\Subrepositories\Packages { diff --git a/src/Api/Suborganizations.php b/src/Api/Suborganizations.php new file mode 100644 index 0000000..614ad9a --- /dev/null +++ b/src/Api/Suborganizations.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PrivatePackagist\ApiClient\Api; + +use PrivatePackagist\ApiClient\Exception\InvalidArgumentException; + +class Suborganizations extends AbstractApi +{ + public function all() + { + return $this->get('/suborganizations/'); + } + + public function show($suborganizationName) + { + return $this->get(sprintf('/suborganizations/%s/', $suborganizationName)); + } + + public function create($name) + { + return $this->post('/suborganizations/', ['name' => $name]); + } + + public function remove($suborganizationName) + { + return $this->delete(sprintf('/suborganizations/%s/', $suborganizationName)); + } + + public function listTeams($suborganizationName) + { + return $this->get(sprintf('/suborganizations/%s/teams/', $suborganizationName)); + } + + public function addOrEditTeams($suborganizationName, array $teams) + { + foreach ($teams as $team) { + if (!isset($team['id'])) { + throw new InvalidArgumentException('Parameter "id" is required.'); + } + + if (!isset($team['permission'])) { + throw new InvalidArgumentException('Parameter "permission" is required.'); + } + } + + return $this->post(sprintf('/suborganizations/%s/teams/', $suborganizationName), $teams); + } + + public function removeTeam($suborganizationName, $teamId) + { + return $this->delete(sprintf('/suborganizations/%s/teams/%s/', $suborganizationName, $teamId)); + } + + public function listTokens($suborganizationName) + { + return $this->get(sprintf('/suborganizations/%s/tokens/', $suborganizationName)); + } + + public function createToken($suborganizationName, array $tokenData) + { + return $this->post(sprintf('/suborganizations/%s/tokens/', $suborganizationName), $tokenData); + } + + public function removeToken($suborganizationName, $tokenId) + { + return $this->delete(sprintf('/suborganizations/%s/tokens/%s/', $suborganizationName, $tokenId)); + } + + public function regenerateToken($suborganizationName, $tokenId, array $confirmation) + { + if (!isset($confirmation['IConfirmOldTokenWillStopWorkingImmediately'])) { + throw new InvalidArgumentException('Confirmation is required to regenerate the Composer repository token.'); + } + + return $this->post(sprintf('/suborganizations/%s/tokens/%s/regenerate', $suborganizationName, $tokenId), $confirmation); + } + + public function packages() + { + return new Suborganizations\Packages($this->client); + } + + public function mirroredRepositories() + { + return new Suborganizations\MirroredRepositories($this->client); + } +} diff --git a/src/Api/Suborganizations/MirroredRepositories.php b/src/Api/Suborganizations/MirroredRepositories.php new file mode 100644 index 0000000..6230369 --- /dev/null +++ b/src/Api/Suborganizations/MirroredRepositories.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PrivatePackagist\ApiClient\Api\Suborganizations; + +use PrivatePackagist\ApiClient\Api\AbstractApi; +use PrivatePackagist\ApiClient\Exception\InvalidArgumentException; + +class MirroredRepositories extends AbstractApi +{ + public function all($suborganizationName) + { + return $this->get(sprintf('/suborganizations/%s/mirrored-repositories/', $suborganizationName)); + } + + public function add($suborganizationName, array $mirroredRepositories) + { + foreach ($mirroredRepositories as $mirroredRepository) { + if (!isset($mirroredRepository['id'], $mirroredRepository['mirroringBehavior'])) { + throw new InvalidArgumentException('The "id" and the "mirroringBehavior" are required to add a mirrored repository to a project'); + } + } + + return $this->post(sprintf('/suborganizations/%s/mirrored-repositories/', $suborganizationName), $mirroredRepositories); + } + + public function show($suborganizationName, $mirroredRepositoryId) + { + return $this->get(sprintf('/suborganizations/%s/mirrored-repositories/%s/', $suborganizationName, $mirroredRepositoryId)); + } + + public function edit($suborganizationName, $mirroredRepositoryId, $mirroringBehavior) + { + return $this->put(sprintf('/suborganizations/%s/mirrored-repositories/%s/', $suborganizationName, $mirroredRepositoryId), [ + 'mirroringBehavior' => $mirroringBehavior, + ]); + } + + public function remove($suborganizationName, $mirroredRepositoryId) + { + return $this->delete(sprintf('/suborganizations/%s/mirrored-repositories/%s/', $suborganizationName, $mirroredRepositoryId)); + } + + public function listPackages($suborganizationName, $mirroredRepositoryId) + { + return $this->get(sprintf('/suborganizations/%s/mirrored-repositories/%s/packages/', $suborganizationName, $mirroredRepositoryId)); + } + + public function addPackages($suborganizationName, $mirroredRepositoryId, array $packages) + { + return $this->post(sprintf('/suborganizations/%s/mirrored-repositories/%s/packages/', $suborganizationName, $mirroredRepositoryId), $packages); + } + + public function removePackages($suborganizationName, $mirroredRepositoryId) + { + return $this->delete(sprintf('/suborganizations/%s/mirrored-repositories/%s/packages/', $suborganizationName, $mirroredRepositoryId)); + } +} diff --git a/src/Api/Suborganizations/Packages.php b/src/Api/Suborganizations/Packages.php new file mode 100644 index 0000000..0289130 --- /dev/null +++ b/src/Api/Suborganizations/Packages.php @@ -0,0 +1,70 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PrivatePackagist\ApiClient\Api\Suborganizations; + +use PrivatePackagist\ApiClient\Api\AbstractApi; +use PrivatePackagist\ApiClient\Exception\InvalidArgumentException; +use PrivatePackagist\ApiClient\Payload\CustomPackageConfig; +use PrivatePackagist\ApiClient\Payload\VcsPackageConfig; + +class Packages extends AbstractApi +{ + public function all($suborganizationName, array $filters = []) + { + if (isset($filters['origin']) && !in_array($filters['origin'], \PrivatePackagist\ApiClient\Api\Packages::AVAILABLE_ORIGINS, true)) { + throw new InvalidArgumentException('Filter "origin" has to be one of: "' . implode('", "', \PrivatePackagist\ApiClient\Api\Packages::AVAILABLE_ORIGINS) . '".'); + } + + return $this->get(sprintf('/suborganizations/%s/packages/', $suborganizationName), $filters); + } + + public function show($suborganizationName, $packageIdOrName) + { + return $this->get(sprintf('/suborganizations/%s/packages/%s', $suborganizationName, $packageIdOrName)); + } + + public function createVcsPackage($suborganizationName, $url, $credentialId = null, $type = 'vcs', $defaultSuborganizationAccess = null) + { + $data = new VcsPackageConfig($url, $credentialId, $type, $defaultSuborganizationAccess); + + return $this->post(sprintf('/suborganizations/%s/packages/', $suborganizationName), $data->toParameters()); + } + + public function createCustomPackage($suborganizationName, $customJson, $credentialId = null, $defaultSuborganizationAccess = null) + { + $data = new CustomPackageConfig($customJson, $credentialId, $defaultSuborganizationAccess); + + return $this->post(sprintf('/suborganizations/%s/packages/', $suborganizationName), $data->toParameters()); + } + + public function editVcsPackage($suborganizationName, $packageIdOrName, $url, $credentialId = null, $type = 'vcs', $defaultSuborganizationAccess = null) + { + $data = new VcsPackageConfig($url, $credentialId, $type, $defaultSuborganizationAccess); + + return $this->put(sprintf('/suborganizations/%s/packages/%s/', $suborganizationName, $packageIdOrName), $data->toParameters()); + } + + public function editCustomPackage($suborganizationName, $packageIdOrName, $customJson, $credentialId = null, $defaultSuborganizationAccess = null) + { + $data = new CustomPackageConfig($customJson, $credentialId, $defaultSuborganizationAccess); + + return $this->put(sprintf('/suborganizations/%s/packages/%s/', $suborganizationName, $packageIdOrName), $data->toParameters()); + } + + public function remove($suborganizationName, $packageIdOrName) + { + return $this->delete(sprintf('/suborganizations/%s/packages/%s/', $suborganizationName, $packageIdOrName)); + } + + public function listDependents($suborganizationName, $packageIdOrName) + { + return $this->get(sprintf('/suborganizations/%s/packages/%s/dependents/', $suborganizationName, $packageIdOrName)); + } +} diff --git a/src/Api/Subrepositories.php b/src/Api/Subrepositories.php index 075825b..1e3d108 100644 --- a/src/Api/Subrepositories.php +++ b/src/Api/Subrepositories.php @@ -11,6 +11,9 @@ use PrivatePackagist\ApiClient\Exception\InvalidArgumentException; +/** + * @deprecated Use the Suborganizations API instead + */ class Subrepositories extends AbstractApi { public function all() diff --git a/src/Api/Subrepositories/MirroredRepositories.php b/src/Api/Subrepositories/MirroredRepositories.php index 8670cae..3875f8a 100644 --- a/src/Api/Subrepositories/MirroredRepositories.php +++ b/src/Api/Subrepositories/MirroredRepositories.php @@ -12,6 +12,9 @@ use PrivatePackagist\ApiClient\Api\AbstractApi; use PrivatePackagist\ApiClient\Exception\InvalidArgumentException; +/** + * @deprecated Use \PrivatePackagist\ApiClient\Api\Suborganizations\MirroredRepositories instead + */ class MirroredRepositories extends AbstractApi { public function all($subrepositoryName) diff --git a/src/Api/Subrepositories/Packages.php b/src/Api/Subrepositories/Packages.php index 9df4ae9..7f0a0b1 100644 --- a/src/Api/Subrepositories/Packages.php +++ b/src/Api/Subrepositories/Packages.php @@ -14,6 +14,9 @@ use PrivatePackagist\ApiClient\Payload\CustomPackageConfig; use PrivatePackagist\ApiClient\Payload\VcsPackageConfig; +/** + * @deprecated Use \PrivatePackagist\ApiClient\Api\Suborganizations\Packages instead + */ class Packages extends AbstractApi { public function all($subrepositoryName, array $filters = []) diff --git a/src/Api/Teams.php b/src/Api/Teams.php index 714bd71..c0aeebb 100644 --- a/src/Api/Teams.php +++ b/src/Api/Teams.php @@ -25,7 +25,7 @@ public function create(string $name, TeamPermissions $permissions): array 'permissions' => [ 'canEditTeamPackages' => (bool) $permissions->canEditTeamPackages, 'canAddPackages' => (bool) $permissions->canAddPackages, - 'canCreateSubrepositories' => (bool) $permissions->canCreateSubrepositories, + 'canCreateSuborganizations' => $permissions->canCreateSuborganizations || $permissions->canCreateSubrepositories, 'canViewVendorCustomers' => (bool) $permissions->canViewVendorCustomers, 'canManageVendorCustomers' => (bool) $permissions->canManageVendorCustomers, ], @@ -46,7 +46,7 @@ public function edit($teamId, string $name, TeamPermissions $permissions): array 'permissions' => [ 'canEditTeamPackages' => (bool) $permissions->canEditTeamPackages, 'canAddPackages' => (bool) $permissions->canAddPackages, - 'canCreateSubrepositories' => (bool) $permissions->canCreateSubrepositories, + 'canCreateSuborganizations' => $permissions->canCreateSuborganizations || $permissions->canCreateSubrepositories, 'canViewVendorCustomers' => (bool) $permissions->canViewVendorCustomers, 'canManageVendorCustomers' => (bool) $permissions->canManageVendorCustomers, ], diff --git a/src/Client.php b/src/Client.php index 381423a..19638cc 100644 --- a/src/Client.php +++ b/src/Client.php @@ -74,19 +74,28 @@ public function customers() } /** - * @deprecated Use Client::subrepositories instead + * @deprecated Use Client::suborganizations instead */ - #[\Deprecated('Use Client::subrepositories instead', '1.16.1')] + #[\Deprecated('Use Client::suborganizations instead', '1.16.1')] public function projects() { return new Api\Subrepositories($this, $this->responseMediator); } + /** + * @deprecated Use Client::suborganizations instead + */ + #[\Deprecated('Use Client::suborganizations instead', '1.38.0')] public function subrepositories() { return new Api\Subrepositories($this, $this->responseMediator); } + public function suborganizations() + { + return new Api\Suborganizations($this, $this->responseMediator); + } + public function organization() { return new Api\Organization($this, $this->responseMediator); diff --git a/src/TeamPermissions.php b/src/TeamPermissions.php index 8024424..0e64f09 100644 --- a/src/TeamPermissions.php +++ b/src/TeamPermissions.php @@ -13,7 +13,10 @@ final class TeamPermissions { public const PERMISSION_CAN_EDIT_TEAM_PACKAGES = 1 << 0; public const PERMISSION_CAN_ADD_PACKAGES = 1 << 1; + /** @deprecated Use PERMISSION_CAN_CREATE_SUBORGANIZATIONS instead */ + #[\Deprecated('Use TeamPermissions::PERMISSION_CAN_CREATE_SUBORGANIZATIONS instead', '1.38.0')] public const PERMISSION_CAN_CREATE_SUBREPOSITORIES = 1 << 2; + public const PERMISSION_CAN_CREATE_SUBORGANIZATIONS = 1 << 2; public const PERMISSION_CAN_VIEW_VENDOR_CUSTOMERS = 1 << 3; public const PERMISSION_CAN_MANAGE_VENDOR_CUSTOMERS = 1 << 4; @@ -21,8 +24,12 @@ final class TeamPermissions public $canEditTeamPackages = false; /** @var bool */ public $canAddPackages = false; - /** @var bool */ + /** + * @var bool + * @deprecated Use $canCreateSuborganizations instead + */ public $canCreateSubrepositories = false; + public $canCreateSuborganizations = false; /** @var bool */ public $canViewVendorCustomers = false; /** @var bool */ @@ -33,7 +40,8 @@ public static function fromFlags(int $flags): self $permissions = new self; $permissions->canEditTeamPackages = ($flags & self::PERMISSION_CAN_EDIT_TEAM_PACKAGES) > 0; $permissions->canAddPackages = ($flags & self::PERMISSION_CAN_ADD_PACKAGES) > 0; - $permissions->canCreateSubrepositories = ($flags & self::PERMISSION_CAN_CREATE_SUBREPOSITORIES) > 0; + $permissions->canCreateSubrepositories = ($flags & self::PERMISSION_CAN_CREATE_SUBORGANIZATIONS) > 0; + $permissions->canCreateSuborganizations = ($flags & self::PERMISSION_CAN_CREATE_SUBORGANIZATIONS) > 0; $permissions->canViewVendorCustomers = ($flags & self::PERMISSION_CAN_VIEW_VENDOR_CUSTOMERS) > 0; $permissions->canManageVendorCustomers = ($flags & self::PERMISSION_CAN_MANAGE_VENDOR_CUSTOMERS) > 0; return $permissions; @@ -41,10 +49,13 @@ public static function fromFlags(int $flags): self public static function fromTeamResponse(array $team): self { + $canCreateSuborganizations = isset($team['permissions']['canCreateSuborganizations']) && $team['permissions']['canCreateSuborganizations'] || isset($team['permissions']['canCreateSubrepositories']) && $team['permissions']['canCreateSubrepositories']; + $permissions = new self; $permissions->canEditTeamPackages = isset($team['permissions']['canEditTeamPackages']) && $team['permissions']['canEditTeamPackages']; $permissions->canAddPackages = isset($team['permissions']['canAddPackages']) && $team['permissions']['canAddPackages']; - $permissions->canCreateSubrepositories = isset($team['permissions']['canCreateSubrepositories']) && $team['permissions']['canCreateSubrepositories']; + $permissions->canCreateSubrepositories = $canCreateSuborganizations; + $permissions->canCreateSuborganizations = $canCreateSuborganizations; $permissions->canViewVendorCustomers = isset($team['permissions']['canViewVendorCustomers']) && $team['permissions']['canViewVendorCustomers']; $permissions->canManageVendorCustomers = isset($team['permissions']['canManageVendorCustomers']) && $team['permissions']['canManageVendorCustomers']; return $permissions; diff --git a/tests/Api/Suborganizations/MirroredRepositoriesTest.php b/tests/Api/Suborganizations/MirroredRepositoriesTest.php new file mode 100644 index 0000000..1421d44 --- /dev/null +++ b/tests/Api/Suborganizations/MirroredRepositoriesTest.php @@ -0,0 +1,170 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PrivatePackagist\ApiClient\Api\Suborganizations; + +use PHPUnit\Framework\MockObject\MockObject; +use PrivatePackagist\ApiClient\Api\ApiTestCase; + +class MirroredRepositoriesTest extends ApiTestCase +{ + public function testAll() + { + $suborganizationName = 'suborganization'; + $expected = [ + $this->getProjectMirroredRepositoryDefinition(), + ]; + + /** @var MirroredRepositories&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/suborganizations/suborganization/mirrored-repositories/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->all($suborganizationName)); + } + + public function testShow() + { + $suborganizationName = 'suborganization'; + $expected = $this->getProjectMirroredRepositoryDefinition(); + + /** @var MirroredRepositories&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/suborganizations/suborganization/mirrored-repositories/1/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->show($suborganizationName, 1)); + } + + public function testAdd() + { + $suborganizationName = 'suborganization'; + $expected = $this->getProjectMirroredRepositoryDefinition(); + $data = [ + 'id' => $expected['mirroredRepository']['id'], + 'mirroringBehavior' => $expected['mirroringBehavior'], + ]; + + /** @var MirroredRepositories&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with($this->equalTo('/suborganizations/suborganization/mirrored-repositories/'), $this->equalTo([$data])) + ->willReturn([$expected]); + + $this->assertSame([$expected], $api->add($suborganizationName, [$data])); + } + + public function testEdit() + { + $suborganizationName = 'suborganization'; + $expected = $this->getProjectMirroredRepositoryDefinition(); + $mirroredRepositoryId = $expected['mirroredRepository']['id']; + $data = [ + 'mirroringBehavior' => $mirroringBehaviour = $expected['mirroringBehavior'], + ]; + + /** @var MirroredRepositories&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with($this->equalTo('/suborganizations/suborganization/mirrored-repositories/1/'), $this->equalTo($data)) + ->willReturn($expected); + + $this->assertSame($expected, $api->edit($suborganizationName, $mirroredRepositoryId, $mirroringBehaviour)); + } + public function testRemove() + { + $suborganizationName = 'suborganization'; + /** @var MirroredRepositories&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with($this->equalTo('/suborganizations/suborganization/mirrored-repositories/1/')) + ->willReturn([]); + + $this->assertSame([], $api->remove($suborganizationName, 1)); + } + + public function testListPackages() + { + $suborganizationName = 'suborganization'; + $expected = [[ + 'name' => 'acme/cool-lib', + 'origin' => 'public-mirror', + 'credentials' => null, + ]]; + /** @var MirroredRepositories&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/suborganizations/suborganization/mirrored-repositories/1/packages/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->listPackages($suborganizationName, 1)); + } + + public function testAddPackages() + { + $suborganizationName = 'suborganization'; + $expected = [[ + 'id' => 'job-id', + 'status' => 'queued', + ]]; + + $packages = [ + 'acme/cool-lib', + ]; + + /** @var MirroredRepositories&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with($this->equalTo('/suborganizations/suborganization/mirrored-repositories/1/packages/'), $this->equalTo($packages)) + ->willReturn($expected); + + $this->assertSame($expected, $api->addPackages($suborganizationName, 1, $packages)); + } + + public function testRemovePackages() + { + $suborganizationName = 'suborganization'; + /** @var MirroredRepositories&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with($this->equalTo('/suborganizations/suborganization/mirrored-repositories/1/packages/')) + ->willReturn([]); + + $this->assertSame([], $api->removePackages($suborganizationName, 1)); + } + + protected function getApiClass() + { + return MirroredRepositories::class; + } + + private function getProjectMirroredRepositoryDefinition() + { + return [ + 'mirroringBehavior' => 'add_on_use', + 'mirroredRepository' => [ + 'id' => 1, + 'name' => 'Packagist.org', + 'url' => 'https://packagist.org', + 'mirroringBehavior' => 'add_on_use', + 'credentials' => null, + ] + ]; + } +} diff --git a/tests/Api/Suborganizations/PackagesTest.php b/tests/Api/Suborganizations/PackagesTest.php new file mode 100644 index 0000000..0753df0 --- /dev/null +++ b/tests/Api/Suborganizations/PackagesTest.php @@ -0,0 +1,220 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PrivatePackagist\ApiClient\Api\Suborganizations; + +use PHPUnit\Framework\MockObject\MockObject; +use PrivatePackagist\ApiClient\Api\ApiTestCase; +use PrivatePackagist\ApiClient\Exception\InvalidArgumentException; + +class PackagesTest extends ApiTestCase +{ + public function testAll() + { + $suborganizationName = 'suborganization'; + $expected = [ + [ + 'id' => 1, + 'name' => 'acme-website/package', + ], + ]; + + /** @var Packages&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/suborganizations/suborganization/packages/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->all($suborganizationName)); + } + + public function testAllWithFilters() + { + $suborganizationName = 'suborganization'; + $expected = [ + [ + 'id' => 1, + 'name' => 'acme-website/package', + ], + ]; + + $filters = [ + 'origin' => \PrivatePackagist\ApiClient\Api\Packages::ORIGIN_PRIVATE, + ]; + + /** @var Packages&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/suborganizations/suborganization/packages/'), $this->equalTo($filters)) + ->willReturn($expected); + + $this->assertSame($expected, $api->all($suborganizationName, $filters)); + } + + public function testAllWithInvalidFilters() + { + $this->expectException(InvalidArgumentException::class); + + $suborganizationName = 'suborganization'; + $filters = [ + 'origin' => 'invalid' + ]; + + /** @var Packages&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->never()) + ->method('get'); + + $api->all($suborganizationName, $filters); + } + + public function testShow() + { + $suborganizationName = 'suborganization'; + $expected = [ + 'id' => 1, + 'name' => 'acme-website/package', + ]; + + /** @var Packages&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/suborganizations/suborganization/packages/acme-website/package')) + ->willReturn($expected); + + $this->assertSame($expected, $api->show($suborganizationName, 'acme-website/package')); + } + + public function testCreateVcsPackage() + { + $suborganizationName = 'suborganization'; + $expected = [ + 'id' => 'job-id', + 'status' => 'queued', + ]; + + /** @var Packages&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with($this->equalTo('/suborganizations/suborganization/packages/'), $this->equalTo(['repoType' => 'vcs', 'repoUrl' => 'localhost', 'credentials' => null])) + ->willReturn($expected); + + $this->assertSame($expected, $api->createVcsPackage($suborganizationName, 'localhost')); + } + + /** + * @dataProvider customProvider + */ + public function testCreateCustomPackage($customJson) + { + $suborganizationName = 'suborganization'; + $expected = [ + 'id' => 'job-id', + 'status' => 'queued', + ]; + + /** @var Packages&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with($this->equalTo('/suborganizations/suborganization/packages/'), $this->equalTo(['repoType' => 'package', 'repoConfig' => '{}', 'credentials' => null])) + ->willReturn($expected); + + $this->assertSame($expected, $api->createCustomPackage($suborganizationName, $customJson)); + } + + public function customProvider() + { + return [ + ['{}'], + [new \stdClass()], + ]; + } + + public function testEditVcsPackage() + { + $suborganizationName = 'suborganization'; + $expected = [ + 'id' => 'job-id', + 'status' => 'queued', + ]; + + /** @var Packages&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with($this->equalTo('/suborganizations/suborganization/packages/acme-website/package/'), $this->equalTo(['repoType' => 'vcs', 'repoUrl' => 'localhost', 'credentials' => null])) + ->willReturn($expected); + + $this->assertSame($expected, $api->editVcsPackage($suborganizationName, 'acme-website/package', 'localhost')); + } + + public function testEditCustomPackage() + { + $suborganizationName = 'suborganization'; + $expected = [ + 'id' => 'job-id', + 'status' => 'queued', + ]; + + /** @var Packages&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('put') + ->with($this->equalTo('/suborganizations/suborganization/packages/acme-website/package/'), $this->equalTo(['repoType' => 'package', 'repoConfig' => '{}', 'credentials' => null])) + ->willReturn($expected); + + $this->assertSame($expected, $api->editCustomPackage($suborganizationName, 'acme-website/package', '{}')); + } + + public function testRemove() + { + $suborganizationName = 'suborganization'; + $expected = []; + + /** @var Packages&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with($this->equalTo('/suborganizations/suborganization/packages/acme-website/package/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->remove($suborganizationName, 'acme-website/package')); + } + + public function testListDependents() + { + $suborganizationName = 'suborganization'; + $packageName = 'acme-website/core-package'; + $expected = [ + [ + 'id' => 1, + 'name' => 'acme-website/package', + ], + ]; + + /** @var Packages&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/suborganizations/suborganization/packages/acme-website/core-package/dependents/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->listDependents($suborganizationName, $packageName)); + } + + protected function getApiClass() + { + return Packages::class; + } +} diff --git a/tests/Api/SuborganizationsTest.php b/tests/Api/SuborganizationsTest.php new file mode 100644 index 0000000..9b28bda --- /dev/null +++ b/tests/Api/SuborganizationsTest.php @@ -0,0 +1,243 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PrivatePackagist\ApiClient\Api; + +use PHPUnit\Framework\MockObject\MockObject; + +class SuborganizationsTest extends ApiTestCase +{ + public function testAll() + { + $expected = [ + $this->getSuborganizationDefinition(), + ]; + + /** @var Suborganizations&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/suborganizations/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->all()); + } + + public function testShow() + { + $expected = $this->getSuborganizationDefinition(); + + $suborganizationName = 'suborganization'; + + /** @var Suborganizations&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/suborganizations/suborganization/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->show($suborganizationName)); + } + + public function testCreate() + { + $expected = $this->getSuborganizationDefinition(); + + /** @var Suborganizations&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with($this->equalTo('/suborganizations/'), $this->equalTo(['name' => 'ACME Websites'])) + ->willReturn($expected); + + $this->assertSame($expected, $api->create('ACME Websites')); + } + + public function testRemove() + { + $expected = ''; + + /** @var Suborganizations&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with($this->equalTo('/suborganizations/suborganization/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->remove('suborganization')); + } + + public function testListTeams() + { + $expected = [ + [ + 'id' => 42, + 'name' => 'Owners', + 'permission' => 'owner', + 'members' => [], + 'suborganizations' => [], + ], + ]; + + /** @var Suborganizations&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/suborganizations/suborganization/teams/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->listTeams('suborganization')); + } + + public function testAddOrEditTeam() + { + $expected = [ + [ + 'id' => 42, + 'name' => 'Owners', + 'permission' => 'owner', + 'members' => [], + 'suborganizations' => [], + ], + ]; + + $teams = [['id' => 42, 'permission' => 'owner']]; + + /** @var Suborganizations&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with($this->equalTo('/suborganizations/suborganization/teams/'), $this->equalTo($teams)) + ->willReturn($expected); + + $this->assertSame($expected, $api->addOrEditTeams('suborganization', $teams)); + } + + public function testRemoveTeam() + { + $expected = ''; + + /** @var Suborganizations&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with($this->equalTo('/suborganizations/suborganization/teams/42/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->removeTeam('suborganization', 42)); + } + + public function testListTokens() + { + $expected = [ + [ + 'description' => 'Generated Client Token', + 'access' => 'read', + 'url' => 'https://vendor-org.repo.packagist.com/acme-websites/', + 'user' => 'token', + 'token' => 'password', + 'lastUsed' => '2018-03-14T11:36:00+00:00' + ], + ]; + + /** @var Suborganizations&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('get') + ->with($this->equalTo('/suborganizations/suborganization/tokens/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->listTokens('suborganization')); + } + + public function testCreateToken() + { + $expected = [ + 'description' => 'Suborganization Token', + 'access' => 'read', + 'url' => 'https://vendor-org.repo.packagist.com/acme-websites/', + 'user' => 'token', + 'token' => 'password', + 'lastUsed' => '2018-03-14T11:36:00+00:00' + ]; + + /** @var Suborganizations&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with($this->equalTo('/suborganizations/suborganization/tokens/'), $this->equalTo([ + 'description' => 'Suborganization Token', + 'access' => 'read', + ])) + ->willReturn($expected); + + $this->assertSame($expected, $api->createToken('suborganization', [ + 'description' => 'Suborganization Token', + 'access' => 'read', + ])); + } + + public function testRemoveToken() + { + $expected = []; + + /** @var Suborganizations&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('delete') + ->with($this->equalTo('/suborganizations/suborganization/tokens/1/')) + ->willReturn($expected); + + $this->assertSame($expected, $api->removeToken('suborganization', 1)); + } + + public function testRegenerateToken() + { + $expected = []; + + /** @var Suborganizations&MockObject $api */ + $api = $this->getApiMock(); + $api->expects($this->once()) + ->method('post') + ->with($this->equalTo('/suborganizations/suborganization/tokens/1/regenerate'), $this->equalTo(['IConfirmOldTokenWillStopWorkingImmediately' => true])) + ->willReturn($expected); + + $this->assertSame($expected, $api->regenerateToken('suborganization', 1, ['IConfirmOldTokenWillStopWorkingImmediately' => true])); + } + + private function getSuborganizationDefinition() + { + return [ + 'id' => 1, + 'name' => 'ACME Websites', + 'urlName' => 'acme-websites', + 'teams' => [ + [ + 'id' => 1, + 'name' => 'Owners', + 'permission' => 'owner', + 'members' => [ + [ + 'id' => 12, + 'username' => 'username' + ] + ], + ] + ] + ]; + } + + /** + * @return string + */ + protected function getApiClass() + { + return Suborganizations::class; + } +} diff --git a/tests/Api/TeamsTest.php b/tests/Api/TeamsTest.php index 3d51384..4d2a143 100644 --- a/tests/Api/TeamsTest.php +++ b/tests/Api/TeamsTest.php @@ -102,7 +102,7 @@ public function testCreateTeam(): void 'permissions' => [ 'canEditTeamPackages' => true, 'canAddPackages' => false, - 'canCreateSubrepositories' => false, + 'canCreateSuborganizations' => false, 'canViewVendorCustomers' => true, 'canManageVendorCustomers' => false, ], @@ -117,7 +117,7 @@ public function testCreateTeam(): void 'permissions' => [ 'canEditTeamPackages' => true, 'canAddPackages' => false, - 'canCreateSubrepositories' => false, + 'canCreateSuborganizations' => false, 'canViewVendorCustomers' => true, 'canManageVendorCustomers' => false, ], @@ -138,7 +138,7 @@ public function testShowTeam(): void 'permissions' => [ 'canEditTeamPackages' => true, 'canAddPackages' => false, - 'canCreateSubrepositories' => false, + 'canCreateSuborganizations' => false, 'canViewVendorCustomers' => true, 'canManageVendorCustomers' => false, ], @@ -165,7 +165,7 @@ public function testEditTeam(): void 'permissions' => [ 'canEditTeamPackages' => true, 'canAddPackages' => false, - 'canCreateSubrepositories' => false, + 'canCreateSuborganizations' => false, 'canViewVendorCustomers' => true, 'canManageVendorCustomers' => false, ], @@ -180,7 +180,7 @@ public function testEditTeam(): void 'permissions' => [ 'canEditTeamPackages' => true, 'canAddPackages' => false, - 'canCreateSubrepositories' => false, + 'canCreateSuborganizations' => false, 'canViewVendorCustomers' => true, 'canManageVendorCustomers' => false, ], @@ -201,7 +201,7 @@ public function testTeamGrant(): void 'permissions' => [ 'canEditTeamPackages' => true, 'canAddPackages' => false, - 'canCreateSubrepositories' => false, + 'canCreateSuborganizations' => false, 'canViewVendorCustomers' => true, 'canManageVendorCustomers' => false, ], @@ -225,7 +225,7 @@ public function testTeamRevoke(): void 'permissions' => [ 'canEditTeamPackages' => true, 'canAddPackages' => false, - 'canCreateSubrepositories' => false, + 'canCreateSuborganizations' => false, 'canViewVendorCustomers' => true, 'canManageVendorCustomers' => false, ], From da7a9dff7d9ef780d634855f8955d75662a1ca73 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 12 Dec 2024 09:27:31 +0000 Subject: [PATCH 3/3] Update README.md Co-authored-by: Steven Rombauts --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 92a6858..ea8fcc8 100644 --- a/README.md +++ b/README.md @@ -568,7 +568,7 @@ Returns a single suborganization. #### Create a suborganization ```php -$suborganization = $client->subrepositories()->create('New suborganization name'); +$suborganization = $client->suborganizations()->create('New suborganization name'); ``` Returns the suborganization.