diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index f1646ca8a..b94f81843 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -7,6 +7,10 @@ on: branches: - master +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: tests: if: | diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 88eb15c9a..22972dd7a 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -6,6 +6,10 @@ on: branches: - master +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: tests: runs-on: ubuntu-22.04 diff --git a/doc/services/identity/v3/application-credentials.rst b/doc/services/identity/v3/application-credentials.rst new file mode 100644 index 000000000..1d16efc95 --- /dev/null +++ b/doc/services/identity/v3/application-credentials.rst @@ -0,0 +1,17 @@ +Application Credentials +======================= + +Add application credential +-------------------------- + +.. sample:: Identity/v3/application_credentials/add_application_credentials.php + +Show application credential details +----------------------------------- + +.. sample:: Identity/v3/application_credentials/show_application_credentials.php + +Delete application credential +----------------------------- + +.. sample:: Identity/v3/application_credentials/delete_application_credentials.php diff --git a/doc/services/identity/v3/index.rst b/doc/services/identity/v3/index.rst index 0ee47ad0d..6520cc7ba 100644 --- a/doc/services/identity/v3/index.rst +++ b/doc/services/identity/v3/index.rst @@ -4,6 +4,7 @@ Identity v3 .. toctree:: :maxdepth: 3 + application-credentials credentials domains endpoints diff --git a/doc/services/identity/v3/tokens.rst b/doc/services/identity/v3/tokens.rst index aff224d19..4802065a0 100644 --- a/doc/services/identity/v3/tokens.rst +++ b/doc/services/identity/v3/tokens.rst @@ -17,6 +17,12 @@ Generate token with username .. sample:: Identity/v3/tokens/generate_token_with_username.php +Generate token with application credential ID +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. sample:: Identity/v3/tokens/generate_token_with_application_credential_id.php + + Generate token from ID ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/samples/Identity/v3/application_credentials/add_application_credential.php b/samples/Identity/v3/application_credentials/add_application_credential.php new file mode 100644 index 000000000..ae92e3766 --- /dev/null +++ b/samples/Identity/v3/application_credentials/add_application_credential.php @@ -0,0 +1,25 @@ + '{authUrl}', + 'region' => '{region}', + 'user' => [ + 'id' => '{userId}', + 'password' => '{password}' + ], + 'scope' => [ + 'project' => [ + 'id' => '{projectId}' + ] + ] +]); + +$identity = $openstack->identityV3(['region' => '{region}']); + +$user = $identity->getUser('{userId}'); +$applicationCredential = $user->createApplicationCredential([ + 'name' => '{name}', + 'description' => '{description}', +]); diff --git a/samples/Identity/v3/application_credentials/delete_application_credential.php b/samples/Identity/v3/application_credentials/delete_application_credential.php new file mode 100644 index 000000000..23619cce2 --- /dev/null +++ b/samples/Identity/v3/application_credentials/delete_application_credential.php @@ -0,0 +1,24 @@ + '{authUrl}', + 'region' => '{region}', + 'user' => [ + 'id' => '{userId}', + 'password' => '{password}' + ], + 'scope' => [ + 'project' => [ + 'id' => '{projectId}' + ] + ] +]); + +$identity = $openstack->identityV3(['region' => '{region}']); + +$user = $identity->getUser('{userId}'); +$applicationCredential = $user->getApplicationCredential('{applicationCredentialId}'); +$applicationCredential->delete(); + diff --git a/samples/Identity/v3/application_credentials/show_application_credential.php b/samples/Identity/v3/application_credentials/show_application_credential.php new file mode 100644 index 000000000..704c63d34 --- /dev/null +++ b/samples/Identity/v3/application_credentials/show_application_credential.php @@ -0,0 +1,24 @@ + '{authUrl}', + 'region' => '{region}', + 'user' => [ + 'id' => '{userId}', + 'password' => '{password}' + ], + 'scope' => [ + 'project' => [ + 'id' => '{projectId}' + ] + ] +]); + +$identity = $openstack->identityV3(['region' => '{region}']); + +$user = $identity->getUser('{userId}'); +$applicationCredential = $user->getApplicationCredential('{applicationCredentialId}'); +$applicationCredential->retrieve(); + diff --git a/samples/Identity/v3/tokens/generate_token_with_application_credential_id.php b/samples/Identity/v3/tokens/generate_token_with_application_credential_id.php new file mode 100644 index 000000000..b64e8a288 --- /dev/null +++ b/samples/Identity/v3/tokens/generate_token_with_application_credential_id.php @@ -0,0 +1,24 @@ + '{authUrl}', + 'region' => '{region}', + 'user' => [ + 'id' => '{userId}', + 'password' => '{password}' + ], + 'scope' => [ + 'project' => ['id' => '{projectId}'] + ] +]); + +$identity = $openstack->identityV3(); + +$token = $identity->generateToken([ + 'application_credential' => [ + 'id' => '{applicationCredentialId}', + 'secret' => '{secret}' + ] +]); diff --git a/samples/Identity/v3/tokens/generate_token_with_username.php b/samples/Identity/v3/tokens/generate_token_with_username.php index cbab6dd52..632de7363 100644 --- a/samples/Identity/v3/tokens/generate_token_with_username.php +++ b/samples/Identity/v3/tokens/generate_token_with_username.php @@ -18,9 +18,8 @@ $identity = $openstack->identityV3(); // Since usernames will not be unique across an entire OpenStack installation, -// when authenticating with them you must also provide your domain ID. You do +// when authenticating with them, you must also provide your domain ID. You do // not have to do this if you authenticate with a user ID. - $token = $identity->generateToken([ 'user' => [ 'name' => '{username}', diff --git a/src/Identity/v3/Api.php b/src/Identity/v3/Api.php index 325e3ac17..cd664668d 100644 --- a/src/Identity/v3/Api.php +++ b/src/Identity/v3/Api.php @@ -19,10 +19,11 @@ public function postTokens(): array 'method' => 'POST', 'path' => 'auth/tokens', 'params' => [ - 'methods' => $this->params->methods(), - 'user' => $this->params->user(), - 'tokenId' => $this->params->tokenBody(), - 'scope' => $this->params->scope(), + 'methods' => $this->params->methods(), + 'user' => $this->params->user(), + 'application_credential' => $this->params->applicationCredential(), + 'tokenId' => $this->params->tokenBody(), + 'scope' => $this->params->scope(), ], ]; } @@ -837,4 +838,43 @@ public function deletePolicy(): array 'params' => ['id' => $this->params->idUrl('policy')], ]; } + + public function getApplicationCredential(): array + { + return [ + 'method' => 'GET', + 'path' => 'users/{userId}/application_credentials/{id}', + 'jsonKey' => 'application_credential', + 'params' => [ + 'id' => $this->params->idUrl('application_credential'), + 'userId' => $this->params->idUrl('user'), + ], + ]; + } + + public function postApplicationCredential(): array + { + return [ + 'method' => 'POST', + 'path' => 'users/{userId}/application_credentials', + 'jsonKey' => 'application_credential', + 'params' => [ + 'userId' => $this->params->idUrl('user'), + 'name' => $this->params->name('application_credential'), + 'description' => $this->params->desc('application_credential'), + ], + ]; + } + + public function deleteApplicationCredential(): array + { + return [ + 'method' => 'DELETE', + 'path' => 'users/{userId}/application_credentials/{id}', + 'params' => [ + 'id' => $this->params->idUrl('application_credential'), + 'userId' => $this->params->idUrl('user'), + ], + ]; + } } diff --git a/src/Identity/v3/Models/ApplicationCredential.php b/src/Identity/v3/Models/ApplicationCredential.php new file mode 100644 index 000000000..32644f2ef --- /dev/null +++ b/src/Identity/v3/Models/ApplicationCredential.php @@ -0,0 +1,69 @@ + 'userId', + ]; + + protected $resourceKey = 'application_credential'; + protected $resourcesKey = 'application_credentials'; + + /** + * {@inheritdoc} + * + * @param array $userOptions {@see \OpenStack\Identity\v3\Api::postApplicationCredential} + */ + public function create(array $userOptions): Creatable + { + $response = $this->execute($this->api->postApplicationCredential(), $userOptions); + + return $this->populateFromResponse($response); + } + + /** + * {@inheritdoc} + */ + public function retrieve() + { + $response = $this->execute( + $this->api->getApplicationCredential(), + ['id' => $this->id, 'userId' => $this->userId] + ); + $this->populateFromResponse($response); + } + + /** + * {@inheritdoc} + */ + public function delete() + { + $this->executeWithState($this->api->deleteApplicationCredential()); + } +} diff --git a/src/Identity/v3/Models/Credential.php b/src/Identity/v3/Models/Credential.php index 5bbd28e11..294a3ec1f 100644 --- a/src/Identity/v3/Models/Credential.php +++ b/src/Identity/v3/Models/Credential.php @@ -39,9 +39,9 @@ class Credential extends OperatorResource implements Creatable, Updateable, Retr 'user_id' => 'userId', ]; - public function create(array $data): Creatable + public function create(array $userOptions): Creatable { - $response = $this->execute($this->api->postCredentials(), $data); + $response = $this->execute($this->api->postCredentials(), $userOptions); return $this->populateFromResponse($response); } diff --git a/src/Identity/v3/Models/Token.php b/src/Identity/v3/Models/Token.php index 56bfcd880..6794b7f8a 100644 --- a/src/Identity/v3/Models/Token.php +++ b/src/Identity/v3/Models/Token.php @@ -4,6 +4,7 @@ namespace OpenStack\Identity\v3\Models; +use InvalidArgumentException; use OpenStack\Common\Resource\Alias; use OpenStack\Common\Resource\Creatable; use OpenStack\Common\Resource\OperatorResource; @@ -94,12 +95,17 @@ public function create(array $data): Creatable if (isset($data['user'])) { $data['methods'] = ['password']; if (!isset($data['user']['id']) && empty($data['user']['domain'])) { - throw new \InvalidArgumentException('When authenticating with a username, you must also provide either the domain name or domain ID to which the user belongs to. Alternatively, if you provide a user ID instead, you do not need to provide domain information.'); + throw new InvalidArgumentException('When authenticating with a username, you must also provide either the domain name '.'or domain ID to which the user belongs to. Alternatively, if you provide a user ID instead, '.'you do not need to provide domain information.'); + } + } elseif (isset($data['application_credential'])) { + $data['methods'] = ['application_credential']; + if (!isset($data['application_credential']['id']) || !isset($data['application_credential']['secret'])) { + throw new InvalidArgumentException('When authenticating with a application_credential, you must provide application credential ID '.' and application credential secret.'); } } elseif (isset($data['tokenId'])) { $data['methods'] = ['token']; } else { - throw new \InvalidArgumentException('Either a user or token must be provided.'); + throw new InvalidArgumentException('Either a user, tokenId or application_credential must be provided.'); } $response = $this->execute($this->api->postTokens(), $data); diff --git a/src/Identity/v3/Models/User.php b/src/Identity/v3/Models/User.php index 7d5f6dd0a..28efc859a 100644 --- a/src/Identity/v3/Models/User.php +++ b/src/Identity/v3/Models/User.php @@ -80,9 +80,7 @@ public function delete() */ public function listGroups(): \Generator { - $options['id'] = $this->id; - - return $this->model(Group::class)->enumerate($this->api->getUserGroups(), $options); + return $this->model(Group::class)->enumerate($this->api->getUserGroups(), ['id' => $this->id]); } /** @@ -92,4 +90,24 @@ public function listProjects(): \Generator { return $this->model(Project::class)->enumerate($this->api->getUserProjects(), ['id' => $this->id]); } + + /** + * Creates a new application credential according to the provided options. + * + * @param array $options {@see \OpenStack\Identity\v3\Api::postApplicationCredential} + */ + public function createApplicationCredential(array $options): ApplicationCredential + { + return $this->model(ApplicationCredential::class)->create(['userId' => $this->id] + $options); + } + + /** + * Retrieves an application credential object and populates its unique identifier object. This operation will not + * perform a GET or HEAD request by default; you will need to call retrieve() if you want to pull in remote state + * from the API. + */ + public function getApplicationCredential(string $id): ApplicationCredential + { + return $this->model(ApplicationCredential::class, ['id' => $id, 'userId' => $this->id]); + } } diff --git a/src/Identity/v3/Params.php b/src/Identity/v3/Params.php index f001d3c48..cba08f5fe 100644 --- a/src/Identity/v3/Params.php +++ b/src/Identity/v3/Params.php @@ -21,6 +21,24 @@ public function methods(): array ]; } + public function applicationCredential(): array + { + return [ + 'type' => self::OBJECT_TYPE, + 'path' => 'auth.identity', + 'properties' => [ + 'id' => [ + 'type' => self::STRING_TYPE, + 'description' => $this->id('application credential id'), + ], + 'secret' => [ + 'type' => self::STRING_TYPE, + 'description' => 'The secret of the application credential', + ], + ], + ]; + } + public function user(): array { return [ diff --git a/src/ObjectStore/v1/Models/Container.php b/src/ObjectStore/v1/Models/Container.php index 7d3d799e5..6448694e8 100644 --- a/src/ObjectStore/v1/Models/Container.php +++ b/src/ObjectStore/v1/Models/Container.php @@ -78,14 +78,14 @@ public function retrieve() } /** - * @param array $data {@see \OpenStack\ObjectStore\v1\Api::putContainer} + * @param array $userOptions {@see \OpenStack\ObjectStore\v1\Api::putContainer} */ - public function create(array $data): Creatable + public function create(array $userOptions): Creatable { - $response = $this->execute($this->api->putContainer(), $data); + $response = $this->execute($this->api->putContainer(), $userOptions); $this->populateFromResponse($response); - $this->name = $data['name']; + $this->name = $userOptions['name']; return $this; } diff --git a/src/ObjectStore/v1/Models/StorageObject.php b/src/ObjectStore/v1/Models/StorageObject.php index 77c40fdb6..c8a91f60f 100644 --- a/src/ObjectStore/v1/Models/StorageObject.php +++ b/src/ObjectStore/v1/Models/StorageObject.php @@ -180,6 +180,7 @@ public function resetMetadata(array $metadata) public function getMetadata(): array { $response = $this->executeWithState($this->api->headObject()); + $this->populateFromResponse($response); return $this->parseMetadata($response); } diff --git a/tests/integration/Identity/v3/ApplicationCredentialsTest.php b/tests/integration/Identity/v3/ApplicationCredentialsTest.php new file mode 100644 index 000000000..fcf68d016 --- /dev/null +++ b/tests/integration/Identity/v3/ApplicationCredentialsTest.php @@ -0,0 +1,97 @@ +service) { + $this->service = Utils::getOpenStack()->identityV3(); + } + + return $this->service; + } + + public function runTests() + { + $this->startTimer(); + + $this->logger->info('-> Generate token'); + $this->token(); + + $this->outputTimeTaken(); + } + + public function token() + { + $this->logStep('Create application credential'); + + $name = $this->randomStr(); + $description = $this->randomStr(); + + /** @var $applicationCredential \OpenStack\Identity\v3\Models\ApplicationCredential */ + require_once $this->sampleFile( + [ + '{name}' => $name, + '{description}' => $description, + ], + 'application_credentials/add_application_credential.php' + ); + self::assertInstanceOf(Models\ApplicationCredential::class, $applicationCredential); + self::assertEquals($name, $applicationCredential->name); + self::assertEquals($description, $applicationCredential->description); + + $this->logStep('Create token with id'); + + /** @var $token \OpenStack\Identity\v3\Models\Token */ + require_once $this->sampleFile( + [ + '{applicationCredentialId}' => $applicationCredential->id, + '{secret}' => $applicationCredential->secret + ], + 'tokens/generate_token_with_application_credential_id.php' + ); + self::assertInstanceOf(Models\Token::class, $token); + + /** @var $result bool */ + require_once $this->sampleFile(['{tokenId}' => $token->id], 'tokens/validate_token.php'); + self::assertTrue($result); + + + $this->logStep('Retrieve application credential'); + $applicationCredentialId = $applicationCredential->id; + $applicationCredential = null; + + /** @var $applicationCredential \OpenStack\Identity\v3\Models\ApplicationCredential */ + require_once $this->sampleFile( + ['{applicationCredentialId}' => $applicationCredentialId], + 'application_credentials/show_application_credential.php' + ); + self::assertInstanceOf(Models\ApplicationCredential::class, $applicationCredential); + self::assertEquals($name, $applicationCredential->name); + self::assertEquals($description, $applicationCredential->description); + + + $this->logStep('Delete application credential'); + require_once $this->sampleFile( + [ + '{applicationCredentialId}' => $applicationCredential->id, + ], + 'application_credentials/delete_application_credential.php' + ); + + /** @var $result bool */ + require_once $this->sampleFile(['{tokenId}' => $token->id], 'tokens/validate_token.php'); + self::assertFalse($result); + } +} \ No newline at end of file diff --git a/tests/integration/Identity/v3/CoreTest.php b/tests/integration/Identity/v3/CoreTest.php index 57175e7c7..0ebb315f0 100644 --- a/tests/integration/Identity/v3/CoreTest.php +++ b/tests/integration/Identity/v3/CoreTest.php @@ -1,6 +1,6 @@ defaultLogging = true; $this->startTimer(); + $this->logger->info('-> Tokens'); $this->tokens(); + + $this->logger->info('-> Domains'); $this->domains(); + $this->logger->info('-> Endpoints'); + $this->endpoints(); + + $this->logger->info('-> Services'); + $this->services(); + + $this->logger->info('-> Groups'); + $this->groups(); + + $this->logger->info('-> Projects'); + $this->projects(); + + $this->logger->info('-> Roles'); + $this->roles(); + + $this->logger->info('-> Users'); + $this->users(); + $this->outputTimeTaken(); } public function tokens() { + $this->logStep('Generate token with user name'); + /** @var $token \OpenStack\Identity\v3\Models\Token */ $path = $this->sampleFile([], 'tokens/generate_token_with_username.php'); require_once $path; self::assertInstanceOf(Models\Token::class, $token); + /** @var $result bool */ + $path = $this->sampleFile(['{tokenId}' => $token->id], 'tokens/validate_token.php'); + require_once $path; + self::assertTrue($result); + + + $this->logStep('Generate token with user id'); + /** @var $token \OpenStack\Identity\v3\Models\Token */ $path = $this->sampleFile([], 'tokens/generate_token_with_user_id.php'); require_once $path; self::assertInstanceOf(Models\Token::class, $token); - $replacements = ['{tokenId}' => $token->id]; + /** @var $result bool */ + $path = $this->sampleFile(['{tokenId}' => $token->id], 'tokens/validate_token.php'); + require_once $path; + self::assertTrue($result); + + $this->logStep('Generate token scoped to project id'); /** @var $token \OpenStack\Identity\v3\Models\Token */ - $path = $this->sampleFile($replacements, 'tokens/generate_token_scoped_to_project_id.php'); + $path = $this->sampleFile([], 'tokens/generate_token_scoped_to_project_id.php'); require_once $path; self::assertInstanceOf(Models\Token::class, $token); + /** @var $result bool */ + $path = $this->sampleFile(['{tokenId}' => $token->id], 'tokens/validate_token.php'); + require_once $path; + self::assertTrue($result); + + + $this->logStep('Generate token scoped to project name'); + /** @var $token \OpenStack\Identity\v3\Models\Token */ - $path = $this->sampleFile($replacements, 'tokens/generate_token_scoped_to_project_name.php'); + $path = $this->sampleFile([], 'tokens/generate_token_scoped_to_project_name.php'); require_once $path; self::assertInstanceOf(Models\Token::class, $token); + /** @var $result bool */ + $path = $this->sampleFile(['{tokenId}' => $token->id], 'tokens/validate_token.php'); + require_once $path; + self::assertTrue($result); + + + $this->logStep('Generate token from id'); /** @var $token \OpenStack\Identity\v3\Models\Token */ - $path = $this->sampleFile($replacements, 'tokens/generate_token_from_id.php'); + $path = $this->sampleFile(['{tokenId}' => $token->id], 'tokens/generate_token_from_id.php'); require_once $path; self::assertInstanceOf(Models\Token::class, $token); /** @var $result bool */ - $path = $this->sampleFile($replacements, 'tokens/validate_token.php'); + $path = $this->sampleFile(['{tokenId}' => $token->id], 'tokens/validate_token.php'); require_once $path; self::assertTrue($result); - $path = $this->sampleFile($replacements, 'tokens/revoke_token.php'); + + $this->logStep('Revoke token'); + + $path = $this->sampleFile(['{tokenId}' => $token->id], 'tokens/revoke_token.php'); require_once $path; /** @var $result bool */ - $path = $this->sampleFile($replacements, 'tokens/validate_token.php'); + $path = $this->sampleFile(['{tokenId}' => $token->id], 'tokens/validate_token.php'); require_once $path; self::assertFalse($result); } public function domains() { + $this->logStep('Create domain'); + $replacements = [ '{name}' => $this->randomStr(), '{description}' => $this->randomStr(), @@ -88,16 +143,25 @@ public function domains() require_once $path; self::assertInstanceOf(Models\Domain::class, $domain); + + $this->logStep('List domains'); + $replacements['{domainId}'] = $domain->id; $path = $this->sampleFile([], 'domains/list_domains.php'); require_once $path; + + $this->logStep('Show domain'); + /** @var $domain \OpenStack\Identity\v3\Models\Domain */ $path = $this->sampleFile($replacements, 'domains/show_domain.php'); require_once $path; self::assertInstanceOf(Models\Domain::class, $domain); + + $this->logStep('Grant and revoke group role'); + $parentRole = $this->getService()->createRole(['name' => $this->randomStr()]); $group = $this->getService()->createGroup(['name' => $this->randomStr(), 'domainId' => $domain->id]); @@ -117,6 +181,9 @@ public function domains() $group->delete(); + + $this->logStep('Grant and revoke user role'); + $user = $this->getService()->createUser(['name' => $this->randomStr(), 'domainId' => $domain->id]); $path = $this->sampleFile($replacements + ['{domainUserId}' => $user->id, '{roleId}' => $parentRole->id], 'domains/grant_user_role.php'); @@ -136,11 +203,17 @@ public function domains() $user->delete(); $parentRole->delete(); + + $this->logStep('Update domain'); + /** @var $domain \OpenStack\Identity\v3\Models\Domain */ $path = $this->sampleFile($replacements, 'domains/update_domain.php'); require_once $path; self::assertInstanceOf(Models\Domain::class, $domain); + + $this->logStep('Delete domain'); + $path = $this->sampleFile($replacements, 'domains/delete_domain.php'); require_once $path; } diff --git a/tests/unit/Identity/v3/Fixtures/application_credential.resp b/tests/unit/Identity/v3/Fixtures/application_credential.resp new file mode 100644 index 000000000..6d38fea19 --- /dev/null +++ b/tests/unit/Identity/v3/Fixtures/application_credential.resp @@ -0,0 +1,31 @@ +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "application_credential": { + "description": "Application credential for monitoring.", + "roles": [ + { + "id": "6aff702516544aeca22817fd3bc39683", + "domain_id": null, + "name": "Reader" + } + ], + "access_rules": [ + { + "path": "/v2.0/metrics", + "id": "07d719df00f349ef8de77d542edf010c", + "service": "monitoring", + "method": "GET" + } + ], + "links": { + "self": "http://example.com/identity/v3/users/fd786d56402c4d1691372e7dee0d00b5/application_credentials/58d61ff8e6e34accb35874016d1dba8b" + }, + "expires_at": "2018-02-27T18:30:59.000000", + "unrestricted": false, + "project_id": "231c62fb0fbd485b995e8b060c3f0d98", + "id": "58d61ff8e6e34accb35874016d1dba8b", + "name": "monitoring" + } +} \ No newline at end of file diff --git a/tests/unit/Identity/v3/Models/ApplicationCredentialTest.php b/tests/unit/Identity/v3/Models/ApplicationCredentialTest.php new file mode 100644 index 000000000..5dd357ac4 --- /dev/null +++ b/tests/unit/Identity/v3/Models/ApplicationCredentialTest.php @@ -0,0 +1,41 @@ +rootFixturesDir = dirname(__DIR__); + + parent::setUp(); + + $this->applicationCredential = new ApplicationCredential($this->client->reveal(), new Api()); + $this->applicationCredential->id = 'APPLICATION_CREDENTIAL_ID'; + $this->applicationCredential->userId = 'USER_ID'; + } + + public function test_it_retrieves() + { + $this->setupMock('GET', 'users/USER_ID/application_credentials/APPLICATION_CREDENTIAL_ID', null, [], 'application_credential'); + + $this->applicationCredential->retrieve(); + + $this->assertEquals('monitoring', $this->applicationCredential->name); + $this->assertEquals(null, $this->applicationCredential->secret); + } + + public function test_it_deletes() + { + $this->setupMock('DELETE', 'users/USER_ID/application_credentials/APPLICATION_CREDENTIAL_ID', null, [], new Response(204)); + + $this->applicationCredential->delete(); + } +} \ No newline at end of file diff --git a/tests/unit/Identity/v3/Models/UserTest.php b/tests/unit/Identity/v3/Models/UserTest.php index b5dce6a5b..7a9a9c61e 100644 --- a/tests/unit/Identity/v3/Models/UserTest.php +++ b/tests/unit/Identity/v3/Models/UserTest.php @@ -65,4 +65,24 @@ public function test_it_lists_projects() $fn = $this->createFn($this->user, 'listProjects', []); $this->listTest($fn, 'users/USER_ID/projects', 'Project', 'projects'); } + + public function test_it_creates_application_credential() + { + $userOptions = [ + 'name' => 'monitoring', + 'description' => 'Application credential for monitoring.', + ]; + + $this->setupMock('POST', 'users/USER_ID/application_credentials', ['application_credential' => $userOptions], [], 'application_credential'); + + $applicationCredential = $this->user->createApplicationCredential($userOptions); + + self::assertEquals('monitoring', $applicationCredential->name); + self::assertEquals('Application credential for monitoring.', $applicationCredential->description); + } + + public function test_it_gets_application_credential() + { + $this->getTest($this->createFn($this->user, 'getApplicationCredential', 'id'), 'ApplicationCredential'); + } }