diff --git a/src/CrowdinApiClient/Api/AbstractApi.php b/src/CrowdinApiClient/Api/AbstractApi.php index bc51fe64..e9cb8422 100644 --- a/src/CrowdinApiClient/Api/AbstractApi.php +++ b/src/CrowdinApiClient/Api/AbstractApi.php @@ -119,17 +119,29 @@ protected function _create(string $path, string $modelName, array $data) /** * @param string $path * @param array $params + * @param string|null $modelName + * @param array $headers * @return mixed */ - protected function _delete(string $path, array $params = []) - { + protected function _delete( + string $path, + array $params = [], + ?string $modelName = null, + array $headers = [] + ) { $options = []; if (!empty($params)) { $options['params'] = $params; } - return $this->client->apiRequest('delete', $path, null, $options); + if (!empty($headers)) { + $options['headers'] = array_merge($this->getHeaders(), $headers); + } + + $decorator = $modelName ? new ResponseModelDecorator($modelName) : null; + + return $this->client->apiRequest('delete', $path, $decorator, $options); } /** diff --git a/src/CrowdinApiClient/Api/BranchApi.php b/src/CrowdinApiClient/Api/BranchApi.php index b4083b04..e1dee305 100644 --- a/src/CrowdinApiClient/Api/BranchApi.php +++ b/src/CrowdinApiClient/Api/BranchApi.php @@ -6,6 +6,7 @@ use CrowdinApiClient\Model\BranchClone; use CrowdinApiClient\Model\BranchMerge; use CrowdinApiClient\Model\BranchMergeSummary; +use CrowdinApiClient\Model\DeleteJob; use CrowdinApiClient\ModelCollection; /** @@ -92,12 +93,34 @@ public function update(Branch $branch): ?Branch * * @param int $projectId * @param int $branchId + * @param string|null $prefer * @return mixed */ - public function delete(int $projectId, int $branchId) + public function delete(int $projectId, int $branchId, ?string $prefer = null) { $path = sprintf('projects/%d/branches/%d', $projectId, $branchId); - return $this->_delete($path); + + if ($prefer === null) { + return $this->_delete($path); + } + + return $this->_delete($path, [], DeleteJob::class, ['prefer' => $prefer]); + } + + /** + * Check Delete Branch Job Status + * @link https://developer.crowdin.com/api/v2/#operation/api.projects.branches.jobs.get API Documentation + * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.branches.jobs.get API Documentation Enterprise + * + * @param int $projectId + * @param int $branchId + * @param string $jobIdentifier + * @return DeleteJob|null + */ + public function checkDeleteStatus(int $projectId, int $branchId, string $jobIdentifier): ?DeleteJob + { + $path = sprintf('projects/%d/branches/%d/jobs/%s', $projectId, $branchId, $jobIdentifier); + return $this->_get($path, DeleteJob::class); } /** diff --git a/src/CrowdinApiClient/Api/DirectoryApi.php b/src/CrowdinApiClient/Api/DirectoryApi.php index c3e6d2e0..07750cd4 100644 --- a/src/CrowdinApiClient/Api/DirectoryApi.php +++ b/src/CrowdinApiClient/Api/DirectoryApi.php @@ -2,6 +2,7 @@ namespace CrowdinApiClient\Api; +use CrowdinApiClient\Model\DeleteJob; use CrowdinApiClient\Model\Directory; use CrowdinApiClient\ModelCollection; @@ -89,11 +90,33 @@ public function update(Directory $directory): ?Directory * * @param int $projectId * @param int $directoryId + * @param string|null $prefer * @return mixed */ - public function delete(int $projectId, int $directoryId) + public function delete(int $projectId, int $directoryId, ?string $prefer = null) { $path = sprintf('projects/%d/directories/%d', $projectId, $directoryId); - return $this->_delete($path); + + if ($prefer === null) { + return $this->_delete($path); + } + + return $this->_delete($path, [], DeleteJob::class, ['prefer' => $prefer]); + } + + /** + * Check Delete Directory Job Status + * @link https://developer.crowdin.com/api/v2/#operation/api.projects.directories.jobs.get API Documentation + * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.directories.jobs.get API Documentation Enterprise + * + * @param int $projectId + * @param int $directoryId + * @param string $jobIdentifier + * @return DeleteJob|null + */ + public function checkDeleteStatus(int $projectId, int $directoryId, string $jobIdentifier): ?DeleteJob + { + $path = sprintf('projects/%d/directories/%d/jobs/%s', $projectId, $directoryId, $jobIdentifier); + return $this->_get($path, DeleteJob::class); } } diff --git a/src/CrowdinApiClient/Api/FileApi.php b/src/CrowdinApiClient/Api/FileApi.php index 8b291f0c..8405a019 100644 --- a/src/CrowdinApiClient/Api/FileApi.php +++ b/src/CrowdinApiClient/Api/FileApi.php @@ -2,6 +2,7 @@ namespace CrowdinApiClient\Api; +use CrowdinApiClient\Model\DeleteJob; use CrowdinApiClient\Model\DownloadFile; use CrowdinApiClient\Model\DownloadFilePreview; use CrowdinApiClient\Model\File; @@ -146,12 +147,34 @@ public function edit(File $file): ?File * @link https://developer.crowdin.com/api/v2/#operation/api.projects.files.delete API Documentation * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.files.delete API Documentation Enterprise * - * @return null + * @param string|null $prefer + * @return mixed */ - public function delete(int $projectId, int $fileId) + public function delete(int $projectId, int $fileId, ?string $prefer = null) { $path = sprintf('projects/%d/files/%d', $projectId, $fileId); - return $this->_delete($path); + + if ($prefer === null) { + return $this->_delete($path); + } + + return $this->_delete($path, [], DeleteJob::class, ['prefer' => $prefer]); + } + + /** + * Check Delete File Job Status + * @link https://developer.crowdin.com/api/v2/#operation/api.projects.files.jobs.get API Documentation + * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.projects.files.jobs.get API Documentation Enterprise + * + * @param int $projectId + * @param int $fileId + * @param string $jobIdentifier + * @return DeleteJob|null + */ + public function checkDeleteStatus(int $projectId, int $fileId, string $jobIdentifier): ?DeleteJob + { + $path = sprintf('projects/%d/files/%d/jobs/%s', $projectId, $fileId, $jobIdentifier); + return $this->_get($path, DeleteJob::class); } /** diff --git a/src/CrowdinApiClient/Model/DeleteJob.php b/src/CrowdinApiClient/Model/DeleteJob.php new file mode 100644 index 00000000..cb3e551b --- /dev/null +++ b/src/CrowdinApiClient/Model/DeleteJob.php @@ -0,0 +1,141 @@ +identifier = (string)$this->getDataProperty('identifier'); + $this->status = (string)$this->getDataProperty('status'); + $this->progress = (int)$this->getDataProperty('progress'); + $this->attributes = (array)$this->getDataProperty('attributes'); + $this->createdAt = (string)$this->getDataProperty('createdAt'); + $this->updatedAt = (string)$this->getDataProperty('updatedAt'); + $this->startedAt = $this->getDataProperty('startedAt'); + $this->finishedAt = $this->getDataProperty('finishedAt'); + $this->error = $this->getDataProperty('error'); + } + + /** + * @return string + */ + public function getIdentifier(): string + { + return $this->identifier; + } + + /** + * @return string + */ + public function getStatus(): string + { + return $this->status; + } + + /** + * @return int + */ + public function getProgress(): int + { + return $this->progress; + } + + /** + * @return array + */ + public function getAttributes(): array + { + return $this->attributes; + } + + /** + * @return string + */ + public function getCreatedAt(): string + { + return $this->createdAt; + } + + /** + * @return string + */ + public function getUpdatedAt(): string + { + return $this->updatedAt; + } + + /** + * @return string|null + */ + public function getStartedAt(): ?string + { + return $this->startedAt; + } + + /** + * @return string|null + */ + public function getFinishedAt(): ?string + { + return $this->finishedAt; + } + + /** + * @return array|null + */ + public function getError(): ?array + { + return $this->error; + } +} diff --git a/tests/CrowdinApiClient/Api/BranchApiTest.php b/tests/CrowdinApiClient/Api/BranchApiTest.php index 47d0b14d..d16b4db1 100644 --- a/tests/CrowdinApiClient/Api/BranchApiTest.php +++ b/tests/CrowdinApiClient/Api/BranchApiTest.php @@ -6,6 +6,7 @@ use CrowdinApiClient\Model\BranchClone; use CrowdinApiClient\Model\BranchMerge; use CrowdinApiClient\Model\BranchMergeSummary; +use CrowdinApiClient\Model\DeleteJob; use CrowdinApiClient\ModelCollection; class BranchApiTest extends AbstractTestApi @@ -133,6 +134,71 @@ public function testDelete() $this->crowdin->branch->delete(2, 34); } + public function testDeleteAsync(): void + { + $this->mockRequest([ + 'path' => '/projects/2/branches/34', + 'method' => 'delete', + 'headers' => [ + 'Authorization' => 'Bearer access_token', + 'content-type' => 'application/json', + 'prefer' => 'respond-async', + ], + 'response' => json_encode([ + 'data' => [ + 'identifier' => '50fb3506-4127-4ba8-8296-f97dc7e3e0c3', + 'status' => 'created', + 'progress' => 0, + 'attributes' => [ + 'branchId' => 34, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:54+00:00', + 'startedAt' => null, + 'finishedAt' => null, + ], + ]), + ]); + + $deleteJob = $this->crowdin->branch->delete(2, 34, 'respond-async'); + + $this->assertInstanceOf(DeleteJob::class, $deleteJob); + $this->assertEquals('50fb3506-4127-4ba8-8296-f97dc7e3e0c3', $deleteJob->getIdentifier()); + $this->assertEquals('created', $deleteJob->getStatus()); + } + + public function testCheckDeleteStatus(): void + { + $this->mockRequestGet( + '/projects/2/branches/34/jobs/50fb3506-4127-4ba8-8296-f97dc7e3e0c3', + json_encode([ + 'data' => [ + 'identifier' => '50fb3506-4127-4ba8-8296-f97dc7e3e0c3', + 'status' => 'finished', + 'progress' => 100, + 'attributes' => [ + 'branchId' => 34, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:56+00:00', + 'startedAt' => '2019-09-23T11:26:55+00:00', + 'finishedAt' => '2019-09-23T11:26:56+00:00', + ], + ]) + ); + + $deleteJob = $this->crowdin->branch->checkDeleteStatus( + 2, + 34, + '50fb3506-4127-4ba8-8296-f97dc7e3e0c3' + ); + + $this->assertInstanceOf(DeleteJob::class, $deleteJob); + $this->assertEquals('finished', $deleteJob->getStatus()); + $this->assertEquals(100, $deleteJob->getProgress()); + $this->assertEquals(['branchId' => 34], $deleteJob->getAttributes()); + } + public function testCloneBranch(): void { $params = [ diff --git a/tests/CrowdinApiClient/Api/DirectoryApiTest.php b/tests/CrowdinApiClient/Api/DirectoryApiTest.php index 95695f47..a3f0439b 100644 --- a/tests/CrowdinApiClient/Api/DirectoryApiTest.php +++ b/tests/CrowdinApiClient/Api/DirectoryApiTest.php @@ -2,6 +2,7 @@ namespace CrowdinApiClient\Tests\Api; +use CrowdinApiClient\Model\DeleteJob; use CrowdinApiClient\Model\Directory; use CrowdinApiClient\ModelCollection; @@ -124,4 +125,68 @@ public function testDelete() $this->mockRequestDelete('/projects/2/directories/34'); $this->crowdin->directory->delete(2, 34); } + + public function testDeleteAsync(): void + { + $this->mockRequest([ + 'path' => '/projects/2/directories/34', + 'method' => 'delete', + 'headers' => [ + 'Authorization' => 'Bearer access_token', + 'content-type' => 'application/json', + 'prefer' => 'respond-async', + ], + 'response' => json_encode([ + 'data' => [ + 'identifier' => '50fb3506-4127-4ba8-8296-f97dc7e3e0c3', + 'status' => 'created', + 'progress' => 0, + 'attributes' => [ + 'directoryId' => 34, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:54+00:00', + 'startedAt' => null, + 'finishedAt' => null, + ], + ]), + ]); + + $deleteJob = $this->crowdin->directory->delete(2, 34, 'respond-async'); + + $this->assertInstanceOf(DeleteJob::class, $deleteJob); + $this->assertEquals('50fb3506-4127-4ba8-8296-f97dc7e3e0c3', $deleteJob->getIdentifier()); + } + + public function testCheckDeleteStatus(): void + { + $this->mockRequestGet( + '/projects/2/directories/34/jobs/50fb3506-4127-4ba8-8296-f97dc7e3e0c3', + json_encode([ + 'data' => [ + 'identifier' => '50fb3506-4127-4ba8-8296-f97dc7e3e0c3', + 'status' => 'finished', + 'progress' => 100, + 'attributes' => [ + 'directoryId' => 34, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:56+00:00', + 'startedAt' => '2019-09-23T11:26:55+00:00', + 'finishedAt' => '2019-09-23T11:26:56+00:00', + ], + ]) + ); + + $deleteJob = $this->crowdin->directory->checkDeleteStatus( + 2, + 34, + '50fb3506-4127-4ba8-8296-f97dc7e3e0c3' + ); + + $this->assertInstanceOf(DeleteJob::class, $deleteJob); + $this->assertEquals('finished', $deleteJob->getStatus()); + $this->assertEquals(100, $deleteJob->getProgress()); + $this->assertEquals(['directoryId' => 34], $deleteJob->getAttributes()); + } } diff --git a/tests/CrowdinApiClient/Api/Enterprise/FileApiTest.php b/tests/CrowdinApiClient/Api/Enterprise/FileApiTest.php index 55cc1503..42f22dea 100644 --- a/tests/CrowdinApiClient/Api/Enterprise/FileApiTest.php +++ b/tests/CrowdinApiClient/Api/Enterprise/FileApiTest.php @@ -4,6 +4,7 @@ namespace CrowdinApiClient\Tests\Api\Enterprise; +use CrowdinApiClient\Model\DeleteJob; use CrowdinApiClient\Model\DownloadFile; use CrowdinApiClient\Model\Enterprise\ReviewedSourceFileBuild; use CrowdinApiClient\ModelCollection; @@ -125,4 +126,36 @@ public function testDownloadReviewedSourceFiles(): void $downloadFile->getUrl() ); } + + public function testDeleteFileAsync(): void + { + $this->mockRequest([ + 'path' => '/projects/2/files/44', + 'method' => 'delete', + 'headers' => [ + 'Authorization' => 'Bearer access_token', + 'content-type' => 'application/json', + 'prefer' => 'respond-async', + ], + 'response' => json_encode([ + 'data' => [ + 'identifier' => '50fb3506-4127-4ba8-8296-f97dc7e3e0c3', + 'status' => 'created', + 'progress' => 0, + 'attributes' => [ + 'fileId' => 44, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:54+00:00', + 'startedAt' => null, + 'finishedAt' => null, + ], + ]), + ]); + + $deleteJob = $this->crowdin->file->delete(2, 44, 'respond-async'); + + $this->assertInstanceOf(DeleteJob::class, $deleteJob); + $this->assertEquals('50fb3506-4127-4ba8-8296-f97dc7e3e0c3', $deleteJob->getIdentifier()); + } } diff --git a/tests/CrowdinApiClient/Api/FileApiTest.php b/tests/CrowdinApiClient/Api/FileApiTest.php index 6deafe93..4cd96742 100644 --- a/tests/CrowdinApiClient/Api/FileApiTest.php +++ b/tests/CrowdinApiClient/Api/FileApiTest.php @@ -2,6 +2,7 @@ namespace CrowdinApiClient\Tests\Api; +use CrowdinApiClient\Model\DeleteJob; use CrowdinApiClient\Model\DownloadFile; use CrowdinApiClient\Model\DownloadFilePreview; use CrowdinApiClient\Model\File; @@ -316,6 +317,70 @@ public function testDelete(): void $this->crowdin->file->delete(2, 44); } + public function testDeleteAsync(): void + { + $this->mockRequest([ + 'path' => '/projects/2/files/44', + 'method' => 'delete', + 'headers' => [ + 'Authorization' => 'Bearer access_token', + 'content-type' => 'application/json', + 'prefer' => 'respond-async', + ], + 'response' => json_encode([ + 'data' => [ + 'identifier' => '50fb3506-4127-4ba8-8296-f97dc7e3e0c3', + 'status' => 'created', + 'progress' => 0, + 'attributes' => [ + 'fileId' => 44, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:54+00:00', + 'startedAt' => null, + 'finishedAt' => null, + ], + ]), + ]); + + $deleteJob = $this->crowdin->file->delete(2, 44, 'respond-async'); + + $this->assertInstanceOf(DeleteJob::class, $deleteJob); + $this->assertEquals('50fb3506-4127-4ba8-8296-f97dc7e3e0c3', $deleteJob->getIdentifier()); + } + + public function testCheckDeleteStatus(): void + { + $this->mockRequestGet( + '/projects/2/files/44/jobs/50fb3506-4127-4ba8-8296-f97dc7e3e0c3', + json_encode([ + 'data' => [ + 'identifier' => '50fb3506-4127-4ba8-8296-f97dc7e3e0c3', + 'status' => 'finished', + 'progress' => 100, + 'attributes' => [ + 'fileId' => 44, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:56+00:00', + 'startedAt' => '2019-09-23T11:26:55+00:00', + 'finishedAt' => '2019-09-23T11:26:56+00:00', + ], + ]) + ); + + $deleteJob = $this->crowdin->file->checkDeleteStatus( + 2, + 44, + '50fb3506-4127-4ba8-8296-f97dc7e3e0c3' + ); + + $this->assertInstanceOf(DeleteJob::class, $deleteJob); + $this->assertEquals('finished', $deleteJob->getStatus()); + $this->assertEquals(100, $deleteJob->getProgress()); + $this->assertEquals(['fileId' => 44], $deleteJob->getAttributes()); + } + public function testDownloadPreview(): void { $this->mockRequestGet( diff --git a/tests/CrowdinApiClient/Model/DeleteJobTest.php b/tests/CrowdinApiClient/Model/DeleteJobTest.php new file mode 100644 index 00000000..7182a46a --- /dev/null +++ b/tests/CrowdinApiClient/Model/DeleteJobTest.php @@ -0,0 +1,63 @@ + '50fb3506-4127-4ba8-8296-f97dc7e3e0c3', + 'status' => 'failed', + 'progress' => 50, + 'attributes' => [ + 'fileId' => 44, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:56+00:00', + 'startedAt' => '2019-09-23T11:26:55+00:00', + 'finishedAt' => null, + 'error' => [ + 'message' => 'The file could not be deleted.', + ], + ]; + + public function testLoadData(): void + { + $deleteJob = new DeleteJob($this->data); + + $this->assertEquals($this->data['identifier'], $deleteJob->getIdentifier()); + $this->assertEquals($this->data['status'], $deleteJob->getStatus()); + $this->assertEquals($this->data['progress'], $deleteJob->getProgress()); + $this->assertEquals($this->data['attributes'], $deleteJob->getAttributes()); + $this->assertEquals($this->data['createdAt'], $deleteJob->getCreatedAt()); + $this->assertEquals($this->data['updatedAt'], $deleteJob->getUpdatedAt()); + $this->assertEquals($this->data['startedAt'], $deleteJob->getStartedAt()); + $this->assertEquals($this->data['finishedAt'], $deleteJob->getFinishedAt()); + $this->assertEquals($this->data['error'], $deleteJob->getError()); + } + + public function testLoadPendingData(): void + { + $deleteJob = new DeleteJob([ + 'identifier' => '50fb3506-4127-4ba8-8296-f97dc7e3e0c3', + 'status' => 'created', + 'progress' => 0, + 'attributes' => [ + 'branchId' => 34, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:54+00:00', + 'startedAt' => null, + 'finishedAt' => null, + ]); + + $this->assertNull($deleteJob->getStartedAt()); + $this->assertNull($deleteJob->getFinishedAt()); + $this->assertNull($deleteJob->getError()); + } +}