Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add suborganization API and deprecated subrepository API #82

Merged
merged 3 commits into from
Dec 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
251 changes: 126 additions & 125 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/Api/Projects.php
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
namespace PrivatePackagist\ApiClient\Api;

/**
* @deprecated Use the Subrepositories API instead
* @deprecated Use the Suborganizations API instead
*/
class Projects extends Subrepositories
{
2 changes: 1 addition & 1 deletion src/Api/Projects/MirroredRepositories.php
Original file line number Diff line number Diff line change
@@ -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
{
2 changes: 1 addition & 1 deletion src/Api/Projects/Packages.php
Original file line number Diff line number Diff line change
@@ -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
{
94 changes: 94 additions & 0 deletions src/Api/Suborganizations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

/**
* (c) Packagist Conductors GmbH <[email protected]>
*
* 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);
}
}
64 changes: 64 additions & 0 deletions src/Api/Suborganizations/MirroredRepositories.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

/**
* (c) Packagist Conductors GmbH <[email protected]>
*
* 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));
}
}
70 changes: 70 additions & 0 deletions src/Api/Suborganizations/Packages.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

/**
* (c) Packagist Conductors GmbH <[email protected]>
*
* 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));
}
}
3 changes: 3 additions & 0 deletions src/Api/Subrepositories.php
Original file line number Diff line number Diff line change
@@ -11,6 +11,9 @@

use PrivatePackagist\ApiClient\Exception\InvalidArgumentException;

/**
* @deprecated Use the Suborganizations API instead
*/
class Subrepositories extends AbstractApi
{
public function all()
3 changes: 3 additions & 0 deletions src/Api/Subrepositories/MirroredRepositories.php
Original file line number Diff line number Diff line change
@@ -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)
3 changes: 3 additions & 0 deletions src/Api/Subrepositories/Packages.php
Original file line number Diff line number Diff line change
@@ -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 = [])
4 changes: 2 additions & 2 deletions src/Api/Teams.php
Original file line number Diff line number Diff line change
@@ -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,
],
13 changes: 11 additions & 2 deletions src/Client.php
Original file line number Diff line number Diff line change
@@ -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);
17 changes: 14 additions & 3 deletions src/TeamPermissions.php
Original file line number Diff line number Diff line change
@@ -13,16 +13,23 @@ 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;

/** @var bool */
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,18 +40,22 @@ 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;
}

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;
170 changes: 170 additions & 0 deletions tests/Api/Suborganizations/MirroredRepositoriesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<?php

/**
* (c) Packagist Conductors GmbH <contact@packagist.com>
*
* 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,
]
];
}
}
220 changes: 220 additions & 0 deletions tests/Api/Suborganizations/PackagesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
<?php

/**
* (c) Packagist Conductors GmbH <contact@packagist.com>
*
* 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;
}
}
243 changes: 243 additions & 0 deletions tests/Api/SuborganizationsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
<?php

/**
* (c) Packagist Conductors GmbH <contact@packagist.com>
*
* 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;
}
}
14 changes: 7 additions & 7 deletions tests/Api/TeamsTest.php
Original file line number Diff line number Diff line change
@@ -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,
],