diff --git a/src/CrowdinApiClient/Api/BranchApi.php b/src/CrowdinApiClient/Api/BranchApi.php index b82f3157..b4083b04 100644 --- a/src/CrowdinApiClient/Api/BranchApi.php +++ b/src/CrowdinApiClient/Api/BranchApi.php @@ -3,6 +3,9 @@ namespace CrowdinApiClient\Api; use CrowdinApiClient\Model\Branch; +use CrowdinApiClient\Model\BranchClone; +use CrowdinApiClient\Model\BranchMerge; +use CrowdinApiClient\Model\BranchMergeSummary; use CrowdinApiClient\ModelCollection; /** @@ -57,7 +60,8 @@ public function get(int $projectId, int $branchId): ?Branch * string $data[name] required Note: Can't contain \\ / : * ? \" < > | symbols
* string $data[title]
* string $data[exportPattern] Note: Can't contain \\ / : * ? \" < > | symbols
- * string $data[priority] Enum: "low" "normal" "high" + * string $data[priority] Enum: "low" "normal" "high"
+ * bool $data[isProtected] String-based projects only * @return Branch|null */ public function create(int $projectId, array $data): ?Branch @@ -95,4 +99,101 @@ public function delete(int $projectId, int $branchId) $path = sprintf('projects/%d/branches/%d', $projectId, $branchId); return $this->_delete($path); } + + /** + * Clone Branch + * @link https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.clones.post API Documentation + * + * @param int $projectId + * @param int $branchId + * @param array $data + * string $data[name] required Note: Can't contain \\ / : * ? \" < > | symbols
+ * string $data[title]
+ * bool $data[isProtected] + * @return BranchClone|null + */ + public function cloneBranch(int $projectId, int $branchId, array $data): ?BranchClone + { + $path = sprintf('projects/%d/branches/%d/clones', $projectId, $branchId); + return $this->_post($path, BranchClone::class, $data); + } + + /** + * Check Branch Clone Status + * @link https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.clones.get API Documentation + * + * @param int $projectId + * @param int $branchId + * @param string $cloneId + * @return BranchClone|null + */ + public function checkCloneStatus(int $projectId, int $branchId, string $cloneId): ?BranchClone + { + $path = sprintf('projects/%d/branches/%d/clones/%s', $projectId, $branchId, $cloneId); + return $this->_get($path, BranchClone::class); + } + + /** + * Get Cloned Branch + * @link https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.clones.branch.get API Documentation + * + * @param int $projectId + * @param int $branchId + * @param string $cloneId + * @return Branch|null + */ + public function getClonedBranch(int $projectId, int $branchId, string $cloneId): ?Branch + { + $path = sprintf('projects/%d/branches/%d/clones/%s/branch', $projectId, $branchId, $cloneId); + return $this->_get($path, Branch::class); + } + + /** + * Merge Branch + * @link https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.merges.post API Documentation + * + * @param int $projectId + * @param int $branchId + * @param array $data + * int $data[sourceBranchId] required
+ * bool $data[deleteAfterMerge]
+ * bool $data[dryRun]
+ * bool $data[acceptSourceChanges] + * @return BranchMerge|null + */ + public function mergeBranch(int $projectId, int $branchId, array $data): ?BranchMerge + { + $path = sprintf('projects/%d/branches/%d/merges', $projectId, $branchId); + return $this->_post($path, BranchMerge::class, $data); + } + + /** + * Check Branch Merge Status + * @link https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.merges.get API Documentation + * + * @param int $projectId + * @param int $branchId + * @param string $mergeId + * @return BranchMerge|null + */ + public function checkMergeStatus(int $projectId, int $branchId, string $mergeId): ?BranchMerge + { + $path = sprintf('projects/%d/branches/%d/merges/%s', $projectId, $branchId, $mergeId); + return $this->_get($path, BranchMerge::class); + } + + /** + * Get Branch Merge Summary + * @link https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.branches.merges.summary.get API Documentation + * + * @param int $projectId + * @param int $branchId + * @param string $mergeId + * @return BranchMergeSummary|null + */ + public function getMergeSummary(int $projectId, int $branchId, string $mergeId): ?BranchMergeSummary + { + $path = sprintf('projects/%d/branches/%d/merges/%s/summary', $projectId, $branchId, $mergeId); + return $this->_get($path, BranchMergeSummary::class); + } } diff --git a/src/CrowdinApiClient/Api/BundleApi.php b/src/CrowdinApiClient/Api/BundleApi.php index 55933be8..14e7b018 100644 --- a/src/CrowdinApiClient/Api/BundleApi.php +++ b/src/CrowdinApiClient/Api/BundleApi.php @@ -2,6 +2,7 @@ namespace CrowdinApiClient\Api; +use CrowdinApiClient\Model\Branch; use CrowdinApiClient\Model\Bundle; use CrowdinApiClient\Model\BundleExport; use CrowdinApiClient\Model\DownloadFile; @@ -116,6 +117,23 @@ public function listFiles(int $projectId, int $bundleId, array $params = []): Mo return $this->_list($path, File::class, $params); } + /** + * List Bundle Branches + * @link https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.bundles.branches.getMany API Documentation + * + * @param int $projectId + * @param int $bundleId + * @param array $params + * integer $params[limit]
+ * integer $params[offset] + * @return ModelCollection + */ + public function listBranches(int $projectId, int $bundleId, array $params = []): ModelCollection + { + $path = sprintf('projects/%d/bundles/%d/branches', $projectId, $bundleId); + return $this->_list($path, Branch::class, $params); + } + /** * Export Bundle * @link https://developer.crowdin.com/api/v2/#operation/api.projects.bundles.exports.post API Documentation diff --git a/src/CrowdinApiClient/Api/DistributionApi.php b/src/CrowdinApiClient/Api/DistributionApi.php index ea6eb016..c0520475 100644 --- a/src/CrowdinApiClient/Api/DistributionApi.php +++ b/src/CrowdinApiClient/Api/DistributionApi.php @@ -51,9 +51,10 @@ public function get(int $projectId, string $hash): ?Distribution * * @param int $projectId * @param array $data - * string $data[exportMode] Enum: "default" "bundle" Default: "default"
+ * string $data[exportMode] Enum: "default" "bundle" Default: "default" Note: String-based projects use "bundle" only
* string $data[name] required
- * int[] $data[fileIds] required
+ * int[] $data[fileIds] Required for file-based projects (default export mode)
+ * int[] $data[bundleIds] Required for string-based projects
* string $data[format] required for 'bundle' export mode
* string $data[exportPattern] required for 'bundle' export mode. Note: Can't contain \\ / : * ? \" < > | symbols
* int[] $data[labelIds]
diff --git a/src/CrowdinApiClient/Api/SourceStringApi.php b/src/CrowdinApiClient/Api/SourceStringApi.php index e84abc5c..a951b312 100644 --- a/src/CrowdinApiClient/Api/SourceStringApi.php +++ b/src/CrowdinApiClient/Api/SourceStringApi.php @@ -3,6 +3,7 @@ namespace CrowdinApiClient\Api; use CrowdinApiClient\Model\SourceString; +use CrowdinApiClient\Model\StringUpload; use CrowdinApiClient\ModelCollection; /** @@ -50,9 +51,10 @@ public function get(int $projectId, int $stringId): ?SourceString * * @param int $projectId * @param array $data - * string $data[identifier] Required for strings-based projects or file-based projects if scheme of CSV file includes identifier column
+ * string $data[identifier] Required for string-based projects or file-based projects if scheme of CSV file includes identifier column
* string $data[text] required
- * integer $data[fileId]
+ * integer $data[branchId] Required for string-based projects
+ * integer $data[fileId] Required for file-based projects
* string $data[context]
* bool $data[isHidden]
* integer $data[maxLength] @@ -110,4 +112,41 @@ public function batchOperations(int $projectId, array $data) $path = sprintf('projects/%d/strings', $projectId); return $this->_patch($path, SourceString::class, $data); } + + /** + * Upload Strings + * @link https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.strings.uploads.post API Documentation + * + * @param int $projectId + * @param array $data + * int $data[storageId] required
+ * int $data[branchId] required
+ * string $data[type]
+ * int $data[parserVersion]
+ * int[] $data[labelIds]
+ * bool $data[updateStrings]
+ * bool $data[cleanupMode]
+ * array $data[importOptions]
+ * string $data[updateOption] + * @return StringUpload|null + */ + public function uploadStrings(int $projectId, array $data): ?StringUpload + { + $path = sprintf('projects/%d/strings/uploads', $projectId); + return $this->_post($path, StringUpload::class, $data); + } + + /** + * Check Upload Strings Status + * @link https://developer.crowdin.com/api/v2/string-based/#operation/api.projects.strings.uploads.get API Documentation + * + * @param int $projectId + * @param string $uploadId + * @return StringUpload|null + */ + public function checkUploadStatus(int $projectId, string $uploadId): ?StringUpload + { + $path = sprintf('projects/%d/strings/uploads/%s', $projectId, $uploadId); + return $this->_get($path, StringUpload::class); + } } diff --git a/src/CrowdinApiClient/Api/TranslationApi.php b/src/CrowdinApiClient/Api/TranslationApi.php index 04183a5a..613d1e28 100644 --- a/src/CrowdinApiClient/Api/TranslationApi.php +++ b/src/CrowdinApiClient/Api/TranslationApi.php @@ -43,7 +43,8 @@ public function listPreTranslations(int $projectId, array $params = []): ModelCo * @param int $projectId * @param array $params * string[] $params[languageIds] required
- * int[] $params[fileIds] required
+ * int[] $params[fileIds] Required for file-based projects
+ * int[] $params[branchIds] String-based projects only
* string $params[method]
* int $params[engineId]
* string $params[autoApproveOption]
diff --git a/src/CrowdinApiClient/Model/Branch.php b/src/CrowdinApiClient/Model/Branch.php index 6af34609..34d81bbf 100644 --- a/src/CrowdinApiClient/Model/Branch.php +++ b/src/CrowdinApiClient/Model/Branch.php @@ -37,6 +37,11 @@ class Branch extends BaseModel */ protected $priority; + /** + * @var bool + */ + protected $isProtected; + /** * @var string */ @@ -57,6 +62,7 @@ public function __construct(array $data = []) $this->title = (string)$this->getDataProperty('title'); $this->exportPattern = (string)$this->getDataProperty('exportPattern'); $this->priority = (string)$this->getDataProperty('priority'); + $this->isProtected = (bool)$this->getDataProperty('isProtected'); $this->createdAt = (string)$this->getDataProperty('createdAt'); $this->updatedAt = (string)$this->getDataProperty('updatedAt'); } @@ -141,6 +147,11 @@ public function setPriority(string $priority): void $this->priority = $priority; } + public function isProtected(): bool + { + return $this->isProtected; + } + /** * @return string */ diff --git a/src/CrowdinApiClient/Model/BranchClone.php b/src/CrowdinApiClient/Model/BranchClone.php new file mode 100644 index 00000000..e35b5f8d --- /dev/null +++ b/src/CrowdinApiClient/Model/BranchClone.php @@ -0,0 +1,103 @@ +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'); + } + + public function getIdentifier(): string + { + return $this->identifier; + } + + public function getStatus(): string + { + return $this->status; + } + + public function getProgress(): int + { + return $this->progress; + } + + public function getAttributes(): array + { + return $this->attributes; + } + + public function getCreatedAt(): string + { + return $this->createdAt; + } + + public function getUpdatedAt(): string + { + return $this->updatedAt; + } + + public function getStartedAt(): ?string + { + return $this->startedAt; + } + + public function getFinishedAt(): ?string + { + return $this->finishedAt; + } +} diff --git a/src/CrowdinApiClient/Model/BranchMerge.php b/src/CrowdinApiClient/Model/BranchMerge.php new file mode 100644 index 00000000..7ab9fc3a --- /dev/null +++ b/src/CrowdinApiClient/Model/BranchMerge.php @@ -0,0 +1,103 @@ +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'); + } + + public function getIdentifier(): string + { + return $this->identifier; + } + + public function getStatus(): string + { + return $this->status; + } + + public function getProgress(): int + { + return $this->progress; + } + + public function getAttributes(): array + { + return $this->attributes; + } + + public function getCreatedAt(): string + { + return $this->createdAt; + } + + public function getUpdatedAt(): string + { + return $this->updatedAt; + } + + public function getStartedAt(): ?string + { + return $this->startedAt; + } + + public function getFinishedAt(): ?string + { + return $this->finishedAt; + } +} diff --git a/src/CrowdinApiClient/Model/BranchMergeSummary.php b/src/CrowdinApiClient/Model/BranchMergeSummary.php new file mode 100644 index 00000000..eef3527e --- /dev/null +++ b/src/CrowdinApiClient/Model/BranchMergeSummary.php @@ -0,0 +1,81 @@ +status = (string)$this->getDataProperty('status'); + $this->sourceBranchId = (int)$this->getDataProperty('sourceBranchId'); + $this->targetBranchId = (int)$this->getDataProperty('targetBranchId'); + $this->dryRun = (bool)$this->getDataProperty('dryRun'); + $this->acceptSourceChanges = (bool)$this->getDataProperty('acceptSourceChanges'); + $this->details = (array)$this->getDataProperty('details'); + } + + public function getStatus(): string + { + return $this->status; + } + + public function getSourceBranchId(): int + { + return $this->sourceBranchId; + } + + public function getTargetBranchId(): int + { + return $this->targetBranchId; + } + + public function isDryRun(): bool + { + return $this->dryRun; + } + + public function isAcceptSourceChanges(): bool + { + return $this->acceptSourceChanges; + } + + public function getDetails(): array + { + return $this->details; + } +} diff --git a/src/CrowdinApiClient/Model/StringUpload.php b/src/CrowdinApiClient/Model/StringUpload.php new file mode 100644 index 00000000..49e85d3f --- /dev/null +++ b/src/CrowdinApiClient/Model/StringUpload.php @@ -0,0 +1,103 @@ +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'); + } + + public function getIdentifier(): string + { + return $this->identifier; + } + + public function getStatus(): string + { + return $this->status; + } + + public function getProgress(): int + { + return $this->progress; + } + + public function getAttributes(): array + { + return $this->attributes; + } + + public function getCreatedAt(): string + { + return $this->createdAt; + } + + public function getUpdatedAt(): string + { + return $this->updatedAt; + } + + public function getStartedAt(): ?string + { + return $this->startedAt; + } + + public function getFinishedAt(): ?string + { + return $this->finishedAt; + } +} diff --git a/tests/CrowdinApiClient/Api/BranchApiTest.php b/tests/CrowdinApiClient/Api/BranchApiTest.php index 80aa6ed0..47d0b14d 100644 --- a/tests/CrowdinApiClient/Api/BranchApiTest.php +++ b/tests/CrowdinApiClient/Api/BranchApiTest.php @@ -3,6 +3,9 @@ namespace CrowdinApiClient\Tests\Api; use CrowdinApiClient\Model\Branch; +use CrowdinApiClient\Model\BranchClone; +use CrowdinApiClient\Model\BranchMerge; +use CrowdinApiClient\Model\BranchMergeSummary; use CrowdinApiClient\ModelCollection; class BranchApiTest extends AbstractTestApi @@ -130,6 +133,193 @@ public function testDelete() $this->crowdin->branch->delete(2, 34); } + public function testCloneBranch(): void + { + $params = [ + 'name' => 'develop-master-clone', + 'title' => 'Clone of Master branch', + ]; + + $this->mockRequest([ + 'path' => '/projects/2/branches/34/clones', + 'method' => 'post', + 'body' => json_encode($params), + 'response' => json_encode([ + 'data' => [ + 'identifier' => 'a3b4c5d6-e7f8-9012-3456-789abc123def', + 'status' => 'created', + 'progress' => 0, + 'attributes' => [], + 'createdAt' => '2023-09-11T11:26:54+00:00', + 'updatedAt' => '2023-09-11T11:26:54+00:00', + 'startedAt' => null, + 'finishedAt' => null, + ], + ]), + ]); + + $clone = $this->crowdin->branch->cloneBranch(2, 34, $params); + + $this->assertInstanceOf(BranchClone::class, $clone); + $this->assertEquals('a3b4c5d6-e7f8-9012-3456-789abc123def', $clone->getIdentifier()); + $this->assertEquals('created', $clone->getStatus()); + $this->assertEquals(0, $clone->getProgress()); + $this->assertEquals('2023-09-11T11:26:54+00:00', $clone->getCreatedAt()); + } + + public function testCheckCloneStatus(): void + { + $this->mockRequestGet( + '/projects/2/branches/34/clones/a3b4c5d6-e7f8-9012-3456-789abc123def', + json_encode([ + 'data' => [ + 'identifier' => 'a3b4c5d6-e7f8-9012-3456-789abc123def', + 'status' => 'finished', + 'progress' => 100, + 'attributes' => [], + 'createdAt' => '2023-09-11T11:26:54+00:00', + 'updatedAt' => '2023-09-11T11:26:57+00:00', + 'startedAt' => '2023-09-11T11:26:55+00:00', + 'finishedAt' => '2023-09-11T11:26:57+00:00', + ], + ]) + ); + + $clone = $this->crowdin->branch->checkCloneStatus(2, 34, 'a3b4c5d6-e7f8-9012-3456-789abc123def'); + + $this->assertInstanceOf(BranchClone::class, $clone); + $this->assertEquals('finished', $clone->getStatus()); + $this->assertEquals(100, $clone->getProgress()); + $this->assertEquals('2023-09-11T11:26:57+00:00', $clone->getFinishedAt()); + } + + public function testGetClonedBranch(): void + { + $this->mockRequestGet( + '/projects/2/branches/34/clones/a3b4c5d6-e7f8-9012-3456-789abc123def/branch', + json_encode([ + 'data' => [ + 'id' => 35, + 'projectId' => 2, + 'name' => 'develop-master-clone', + 'title' => 'Clone of Master branch', + 'isProtected' => false, + 'createdAt' => '2023-09-11T11:26:57+00:00', + 'updatedAt' => null, + ], + ]) + ); + + $branch = $this->crowdin->branch->getClonedBranch(2, 34, 'a3b4c5d6-e7f8-9012-3456-789abc123def'); + + $this->assertInstanceOf(Branch::class, $branch); + $this->assertEquals(35, $branch->getId()); + $this->assertEquals(2, $branch->getProjectId()); + $this->assertEquals('develop-master-clone', $branch->getName()); + $this->assertFalse($branch->isProtected()); + } + + public function testMergeBranch(): void + { + $params = [ + 'sourceBranchId' => 33, + 'deleteAfterMerge' => false, + ]; + + $this->mockRequest([ + 'path' => '/projects/2/branches/34/merges', + 'method' => 'post', + 'body' => json_encode($params), + 'response' => json_encode([ + 'data' => [ + 'identifier' => 'b4c5d6e7-f8a9-0123-4567-890bcd234efa', + 'status' => 'created', + 'progress' => 0, + 'attributes' => [ + 'sourceBranchId' => 33, + 'deleteAfterMerge' => false, + 'dryRun' => false, + 'acceptSourceChanges' => false, + ], + 'createdAt' => '2023-09-11T11:26:54+00:00', + 'updatedAt' => '2023-09-11T11:26:54+00:00', + 'startedAt' => null, + 'finishedAt' => null, + ], + ]), + ]); + + $merge = $this->crowdin->branch->mergeBranch(2, 34, $params); + + $this->assertInstanceOf(BranchMerge::class, $merge); + $this->assertEquals('b4c5d6e7-f8a9-0123-4567-890bcd234efa', $merge->getIdentifier()); + $this->assertEquals('created', $merge->getStatus()); + $this->assertEquals(0, $merge->getProgress()); + } + + public function testCheckMergeStatus(): void + { + $this->mockRequestGet( + '/projects/2/branches/34/merges/b4c5d6e7-f8a9-0123-4567-890bcd234efa', + json_encode([ + 'data' => [ + 'identifier' => 'b4c5d6e7-f8a9-0123-4567-890bcd234efa', + 'status' => 'finished', + 'progress' => 100, + 'attributes' => [ + 'sourceBranchId' => 33, + 'deleteAfterMerge' => false, + 'dryRun' => false, + 'acceptSourceChanges' => false, + ], + 'createdAt' => '2023-09-11T11:26:54+00:00', + 'updatedAt' => '2023-09-11T11:26:56+00:00', + 'startedAt' => '2023-09-11T11:26:55+00:00', + 'finishedAt' => '2023-09-11T11:26:56+00:00', + ], + ]) + ); + + $merge = $this->crowdin->branch->checkMergeStatus(2, 34, 'b4c5d6e7-f8a9-0123-4567-890bcd234efa'); + + $this->assertInstanceOf(BranchMerge::class, $merge); + $this->assertEquals('finished', $merge->getStatus()); + $this->assertEquals(100, $merge->getProgress()); + $this->assertEquals('2023-09-11T11:26:56+00:00', $merge->getFinishedAt()); + } + + public function testGetMergeSummary(): void + { + $this->mockRequestGet( + '/projects/2/branches/34/merges/b4c5d6e7-f8a9-0123-4567-890bcd234efa/summary', + json_encode([ + 'data' => [ + 'status' => 'merged', + 'sourceBranchId' => 33, + 'targetBranchId' => 34, + 'dryRun' => false, + 'acceptSourceChanges' => false, + 'details' => [ + 'added' => 5, + 'deleted' => 1, + 'updated' => 3, + 'conflicted' => 0, + ], + ], + ]) + ); + + $summary = $this->crowdin->branch->getMergeSummary(2, 34, 'b4c5d6e7-f8a9-0123-4567-890bcd234efa'); + + $this->assertInstanceOf(BranchMergeSummary::class, $summary); + $this->assertEquals('merged', $summary->getStatus()); + $this->assertEquals(33, $summary->getSourceBranchId()); + $this->assertEquals(34, $summary->getTargetBranchId()); + $this->assertFalse($summary->isDryRun()); + $this->assertFalse($summary->isAcceptSourceChanges()); + $this->assertEquals(['added' => 5, 'deleted' => 1, 'updated' => 3, 'conflicted' => 0], $summary->getDetails()); + } + public function testUpdate() { $mock = $this->mockClient diff --git a/tests/CrowdinApiClient/Api/BundleApiTest.php b/tests/CrowdinApiClient/Api/BundleApiTest.php index 7362158e..b7439fbc 100644 --- a/tests/CrowdinApiClient/Api/BundleApiTest.php +++ b/tests/CrowdinApiClient/Api/BundleApiTest.php @@ -2,6 +2,7 @@ namespace CrowdinApiClient\Tests\Api; +use CrowdinApiClient\Model\Branch; use CrowdinApiClient\Model\Bundle; use CrowdinApiClient\Model\BundleExport; use CrowdinApiClient\Model\DownloadFile; @@ -218,6 +219,42 @@ public function testListFiles(): void $this->assertEquals(44, $files[0]->getId()); } + public function testListBranches(): void + { + $this->mockRequest([ + 'path' => '/projects/2/bundles/34/branches', + 'method' => 'get', + 'response' => json_encode([ + 'data' => [ + [ + 'data' => [ + 'id' => 10, + 'projectId' => 2, + 'name' => 'develop-master', + 'title' => 'Master branch', + 'isProtected' => false, + 'createdAt' => '2023-09-11T11:26:54+00:00', + 'updatedAt' => null, + ], + ], + ], + 'pagination' => [ + 'offset' => 0, + 'limit' => 25, + ], + ]), + ]); + + $branches = $this->crowdin->bundle->listBranches(2, 34); + + $this->assertInstanceOf(ModelCollection::class, $branches); + $this->assertCount(1, $branches); + $this->assertInstanceOf(Branch::class, $branches[0]); + $this->assertEquals(10, $branches[0]->getId()); + $this->assertEquals('develop-master', $branches[0]->getName()); + $this->assertFalse($branches[0]->isProtected()); + } + public function testExport(): void { $params = []; diff --git a/tests/CrowdinApiClient/Api/SourceStringApiTest.php b/tests/CrowdinApiClient/Api/SourceStringApiTest.php index b8fc3a1c..c7633f99 100644 --- a/tests/CrowdinApiClient/Api/SourceStringApiTest.php +++ b/tests/CrowdinApiClient/Api/SourceStringApiTest.php @@ -3,6 +3,7 @@ namespace CrowdinApiClient\Tests\Api; use CrowdinApiClient\Model\SourceString; +use CrowdinApiClient\Model\StringUpload; use CrowdinApiClient\ModelCollection; class SourceStringApiTest extends AbstractTestApi @@ -221,4 +222,71 @@ public function testBatch() $this->assertInstanceOf(SourceString::class, $batchResult); } + + public function testUploadStrings(): void + { + $params = [ + 'storageId' => 1001, + 'branchId' => 34, + ]; + + $this->mockRequest([ + 'path' => '/projects/2/strings/uploads', + 'method' => 'post', + 'body' => json_encode($params), + 'response' => json_encode([ + 'data' => [ + 'identifier' => 'c5d6e7f8-a9b0-1234-5678-901cde345fab', + 'status' => 'created', + 'progress' => 0, + 'attributes' => [ + 'storageId' => 1001, + 'branchId' => 34, + ], + 'createdAt' => '2023-09-11T11:26:54+00:00', + 'updatedAt' => '2023-09-11T11:26:54+00:00', + 'startedAt' => null, + 'finishedAt' => null, + ], + ]), + ]); + + $upload = $this->crowdin->sourceString->uploadStrings(2, $params); + + $this->assertInstanceOf(StringUpload::class, $upload); + $this->assertEquals('c5d6e7f8-a9b0-1234-5678-901cde345fab', $upload->getIdentifier()); + $this->assertEquals('created', $upload->getStatus()); + $this->assertEquals(0, $upload->getProgress()); + $this->assertEquals(['storageId' => 1001, 'branchId' => 34], $upload->getAttributes()); + } + + public function testCheckUploadStatus(): void + { + $this->mockRequestGet( + '/projects/2/strings/uploads/c5d6e7f8-a9b0-1234-5678-901cde345fab', + json_encode([ + 'data' => [ + 'identifier' => 'c5d6e7f8-a9b0-1234-5678-901cde345fab', + 'status' => 'finished', + 'progress' => 100, + 'attributes' => [ + 'storageId' => 1001, + 'branchId' => 34, + ], + 'createdAt' => '2023-09-11T11:26:54+00:00', + 'updatedAt' => '2023-09-11T11:26:56+00:00', + 'startedAt' => '2023-09-11T11:26:55+00:00', + 'finishedAt' => '2023-09-11T11:26:56+00:00', + ], + ]) + ); + + $upload = $this->crowdin->sourceString->checkUploadStatus(2, 'c5d6e7f8-a9b0-1234-5678-901cde345fab'); + + $this->assertInstanceOf(StringUpload::class, $upload); + $this->assertEquals('finished', $upload->getStatus()); + $this->assertEquals(100, $upload->getProgress()); + $this->assertEquals('2023-09-11T11:26:56+00:00', $upload->getFinishedAt()); + $this->assertEquals('2023-09-11T11:26:55+00:00', $upload->getStartedAt()); + } }