diff --git a/src/CrowdinApiClient/Api/UserApi.php b/src/CrowdinApiClient/Api/UserApi.php index 4a7f5643..3f1da006 100644 --- a/src/CrowdinApiClient/Api/UserApi.php +++ b/src/CrowdinApiClient/Api/UserApi.php @@ -2,9 +2,12 @@ namespace CrowdinApiClient\Api; +use CrowdinApiClient\Model\HourlyUserReportSettingsTemplate; use CrowdinApiClient\Model\ProjectMember; use CrowdinApiClient\Model\ProjectMemberAddedStatistics; +use CrowdinApiClient\Model\Report; use CrowdinApiClient\Model\User; +use CrowdinApiClient\Model\UserReportSettingsTemplate; use CrowdinApiClient\ModelCollection; /** @@ -138,4 +141,116 @@ public function deleteMemberFromProject(int $projectId, int $memberId): void { $this->_delete(sprintf('projects/%d/members/%s', $projectId, $memberId)); } + + /** + * List User Report Settings Templates + * @link https://developer.crowdin.com/api/v2/#operation/api.users.reports.settings-templates.getMany API Documentation + * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.users.reports.settings-templates.getMany API Documentation Enterprise + * + * @param int $userId + * @param array $params + * integer $params[limit]
+ * integer $params[offset] + * @return ModelCollection + */ + public function listReportSettingsTemplates(int $userId, array $params = []): ModelCollection + { + $options = []; + if ($params !== []) { + $options['params'] = $params; + } + + $path = sprintf('users/%d/reports/settings-templates', $userId); + $response = $this->client->apiRequest('get', $path, null, $options); + + $modelCollection = new ModelCollection(); + $modelCollection->setPagination($response['pagination']); + + foreach ($response['data'] as $item) { + $modelCollection->add($this->makeUserReportSettingsTemplate($item['data'])); + } + + return $modelCollection; + } + + /** + * Create User Report Settings Template + * @link https://developer.crowdin.com/api/v2/#operation/api.users.reports.settings-templates.post API Documentation + * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.users.reports.settings-templates.post API Documentation Enterprise + * + * @param int $userId + * @param array $data + * string $data[name] required
+ * string $data[currency] required
+ * string $data[unit] required
+ * array $data[config] required + * @return UserReportSettingsTemplate|HourlyUserReportSettingsTemplate|null + */ + public function createReportSettingsTemplate(int $userId, array $data) + { + $path = sprintf('users/%d/reports/settings-templates', $userId); + $options = ['body' => json_encode($data), 'headers' => $this->getHeaders()]; + $response = $this->client->apiRequest('post', $path, null, $options); + + return $this->makeUserReportSettingsTemplate($response['data']); + } + + /** + * Get User Report Settings Template + * @link https://developer.crowdin.com/api/v2/#operation/api.users.reports.settings-templates.get API Documentation + * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.users.reports.settings-templates.get API Documentation Enterprise + * + * @param int $userId + * @param int $reportSettingsTemplateId + * @return UserReportSettingsTemplate|HourlyUserReportSettingsTemplate|null + */ + public function getReportSettingsTemplate(int $userId, int $reportSettingsTemplateId) + { + $path = sprintf('users/%d/reports/settings-templates/%d', $userId, $reportSettingsTemplateId); + $response = $this->client->apiRequest('get', $path); + + return $this->makeUserReportSettingsTemplate($response['data']); + } + + /** + * Delete User Report Settings Template + * @link https://developer.crowdin.com/api/v2/#operation/api.users.reports.settings-templates.delete API Documentation + * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.users.reports.settings-templates.delete API Documentation Enterprise + * + * @param int $userId + * @param int $reportSettingsTemplateId + */ + public function deleteReportSettingsTemplate(int $userId, int $reportSettingsTemplateId): void + { + $this->_delete(sprintf('users/%d/reports/settings-templates/%d', $userId, $reportSettingsTemplateId)); + } + + /** + * Update User Report Settings Template + * @link https://developer.crowdin.com/api/v2/#operation/api.users.reports.settings-templates.patch API Documentation + * @link https://developer.crowdin.com/enterprise/api/v2/#operation/api.users.reports.settings-templates.patch API Documentation Enterprise + * + * @param int $userId + * @param UserReportSettingsTemplate|HourlyUserReportSettingsTemplate $reportSettingsTemplate + * @return UserReportSettingsTemplate|HourlyUserReportSettingsTemplate|null + */ + public function updateReportSettingsTemplate(int $userId, $reportSettingsTemplate) + { + return $this->_update( + sprintf('users/%d/reports/settings-templates/%d', $userId, $reportSettingsTemplate->getId()), + $reportSettingsTemplate + ); + } + + /** + * @return HourlyUserReportSettingsTemplate|UserReportSettingsTemplate + */ + private function makeUserReportSettingsTemplate(array $data) + { + if (($data['unit'] ?? '') === Report::UNIT_HOURS) { + return new HourlyUserReportSettingsTemplate($data); + } + + return new UserReportSettingsTemplate($data); + } } diff --git a/src/CrowdinApiClient/Model/AbstractUserReportSettingsTemplate.php b/src/CrowdinApiClient/Model/AbstractUserReportSettingsTemplate.php new file mode 100644 index 00000000..f6dc4918 --- /dev/null +++ b/src/CrowdinApiClient/Model/AbstractUserReportSettingsTemplate.php @@ -0,0 +1,128 @@ +id; + } + + public function getName(): string + { + return $this->name; + } + + public function setName(string $name): void + { + $this->name = $name; + } + + public function getCurrency(): string + { + return $this->currency; + } + + public function setCurrency(string $currency): void + { + if (!in_array($currency, Report::CURRENCIES, true)) { + throw new InvalidArgumentException( + sprintf( + 'Argument "currency" must be one of the following values: %s', + implode(', ', Report::CURRENCIES) + ) + ); + } + + $this->currency = $currency; + } + + public function getUnit(): string + { + return $this->unit; + } + + public function setUnit(string $unit): void + { + if (!in_array($unit, static::SUPPORTED_UNITS, true)) { + throw new InvalidArgumentException( + sprintf( + 'Argument "unit" must be one of the following values: %s', + implode(', ', static::SUPPORTED_UNITS) + ) + ); + } + + $this->unit = $unit; + } + + public function getCreatedAt(): string + { + return $this->createdAt; + } + + public function getUpdatedAt(): ?string + { + return $this->updatedAt; + } + + public function toArray(): array + { + return [ + 'id' => $this->id, + 'name' => $this->name, + 'currency' => $this->currency, + 'unit' => $this->unit, + 'config' => $this->config->toArray(), + 'createdAt' => $this->createdAt, + 'updatedAt' => $this->updatedAt, + ]; + } + + abstract public function getConfig(); + + abstract public function setConfig($config): void; +} diff --git a/src/CrowdinApiClient/Model/HourlyBaseRates.php b/src/CrowdinApiClient/Model/HourlyBaseRates.php new file mode 100644 index 00000000..d37cf539 --- /dev/null +++ b/src/CrowdinApiClient/Model/HourlyBaseRates.php @@ -0,0 +1,40 @@ +hourly = (float)$this->getDataProperty('hourly'); + } + + public function getHourly(): float + { + return $this->hourly; + } + + public function setHourly(float $hourly): void + { + $this->hourly = $hourly; + } + + public function toArray(): array + { + return [ + 'hourly' => $this->hourly, + ]; + } +} diff --git a/src/CrowdinApiClient/Model/HourlyIndividualRates.php b/src/CrowdinApiClient/Model/HourlyIndividualRates.php new file mode 100644 index 00000000..71e13a31 --- /dev/null +++ b/src/CrowdinApiClient/Model/HourlyIndividualRates.php @@ -0,0 +1,112 @@ +languageIds = array_map(static function ($languageId): string { + return (string)$languageId; + }, $this->getDataProperty('languageIds') ?? []); + $this->userIds = array_map(static function ($userId): int { + return (int)$userId; + }, $this->getDataProperty('userIds') ?? []); + $this->hourly = (float)$this->getDataProperty('hourly'); + } + + /** + * @return string[] + */ + public function getLanguageIds(): array + { + return $this->languageIds; + } + + /** + * @param string[] $languageIds + */ + public function setLanguageIds(array $languageIds): void + { + if ($languageIds === []) { + throw new InvalidArgumentException('Argument "languageIds" cannot be empty'); + } + + foreach ($languageIds as $languageId) { + if (!is_string($languageId)) { + throw new InvalidArgumentException('Argument "languageIds" must be an array of strings'); + } + } + + $this->languageIds = $languageIds; + } + + /** + * @return int[] + */ + public function getUserIds(): array + { + return $this->userIds; + } + + /** + * @param int[] $userIds + */ + public function setUserIds(array $userIds): void + { + if ($userIds === []) { + throw new InvalidArgumentException('Argument "userIds" cannot be empty'); + } + + foreach ($userIds as $userId) { + if (!is_int($userId)) { + throw new InvalidArgumentException('Argument "userIds" must be an array of integers'); + } + } + + $this->userIds = $userIds; + } + + public function getHourly(): float + { + return $this->hourly; + } + + public function setHourly(float $hourly): void + { + $this->hourly = $hourly; + } + + public function toArray(): array + { + return [ + 'languageIds' => $this->languageIds, + 'userIds' => $this->userIds, + 'hourly' => $this->hourly, + ]; + } +} diff --git a/src/CrowdinApiClient/Model/HourlyReportSettingsTemplateConfig.php b/src/CrowdinApiClient/Model/HourlyReportSettingsTemplateConfig.php new file mode 100644 index 00000000..ee2d8e6f --- /dev/null +++ b/src/CrowdinApiClient/Model/HourlyReportSettingsTemplateConfig.php @@ -0,0 +1,81 @@ +baseRates = new HourlyBaseRates($this->getDataProperty('baseRates') ?? []); + $this->individualRates = array_map(static function (array $individualRates): HourlyIndividualRates { + return new HourlyIndividualRates($individualRates); + }, $this->getDataProperty('individualRates') ?? []); + } + + public function getBaseRates(): HourlyBaseRates + { + return $this->baseRates; + } + + public function setBaseRates(HourlyBaseRates $baseRates): void + { + $this->baseRates = $baseRates; + } + + /** + * @return HourlyIndividualRates[] + */ + public function getIndividualRates(): array + { + return $this->individualRates; + } + + /** + * @param HourlyIndividualRates[] $individualRates + */ + public function setIndividualRates(array $individualRates): void + { + if ($individualRates === []) { + throw new InvalidArgumentException('Argument "individualRates" cannot be empty'); + } + + foreach ($individualRates as $individualRate) { + if (!$individualRate instanceof HourlyIndividualRates) { + throw new InvalidArgumentException( + 'Argument "individualRates" must contain only HourlyIndividualRates objects' + ); + } + } + + $this->individualRates = $individualRates; + } + + public function toArray(): array + { + return [ + 'baseRates' => $this->baseRates->toArray(), + 'individualRates' => array_map(static function (HourlyIndividualRates $individualRate): array { + return $individualRate->toArray(); + }, $this->individualRates), + ]; + } +} diff --git a/src/CrowdinApiClient/Model/HourlyUserReportSettingsTemplate.php b/src/CrowdinApiClient/Model/HourlyUserReportSettingsTemplate.php new file mode 100644 index 00000000..efd85ea1 --- /dev/null +++ b/src/CrowdinApiClient/Model/HourlyUserReportSettingsTemplate.php @@ -0,0 +1,60 @@ +id = (int)$this->getDataProperty('id'); + $this->name = (string)$this->getDataProperty('name'); + $this->currency = (string)$this->getDataProperty('currency'); + $this->config = new HourlyReportSettingsTemplateConfig($this->getDataProperty('config') ?? []); + $this->createdAt = (string)$this->getDataProperty('createdAt'); + $this->updatedAt = $this->getDataProperty('updatedAt') ? (string)$this->getDataProperty('updatedAt') : null; + } + + public function getConfig(): HourlyReportSettingsTemplateConfig + { + return $this->config; + } + + /** + * @param HourlyReportSettingsTemplateConfig $config + */ + public function setConfig($config): void + { + $this->config = $config; + } + + /** + * @return array + */ + public function toArray(): array + { + return [ + 'id' => $this->id, + 'name' => $this->name, + 'currency' => $this->currency, + 'unit' => $this->unit, + 'config' => $this->config->toArray(), + 'createdAt' => $this->createdAt, + 'updatedAt' => $this->updatedAt, + ]; + } +} diff --git a/src/CrowdinApiClient/Model/IndividualRates.php b/src/CrowdinApiClient/Model/IndividualRates.php index e14ae577..5a652fd1 100644 --- a/src/CrowdinApiClient/Model/IndividualRates.php +++ b/src/CrowdinApiClient/Model/IndividualRates.php @@ -54,7 +54,7 @@ public function getLanguageIds(): array } /** - * @param array $languageIds + * @param string[] $languageIds */ public function setLanguageIds(array $languageIds): void { diff --git a/src/CrowdinApiClient/Model/Report.php b/src/CrowdinApiClient/Model/Report.php index 60ffe655..ba67962a 100644 --- a/src/CrowdinApiClient/Model/Report.php +++ b/src/CrowdinApiClient/Model/Report.php @@ -61,12 +61,14 @@ class Report extends BaseModel public const UNIT_WORDS = 'words'; public const UNIT_CHARS = 'chars'; public const UNIT_CHARS_WITH_SPACES = 'chars_with_spaces'; + public const UNIT_HOURS = 'hours'; public const UNITS = [ self::UNIT_STRINGS, self::UNIT_WORDS, self::UNIT_CHARS, self::UNIT_CHARS_WITH_SPACES, + self::UNIT_HOURS, ]; /** diff --git a/src/CrowdinApiClient/Model/ReportSettingsTemplateConfig.php b/src/CrowdinApiClient/Model/ReportSettingsTemplateConfig.php index 6e93df51..1b4580ba 100644 --- a/src/CrowdinApiClient/Model/ReportSettingsTemplateConfig.php +++ b/src/CrowdinApiClient/Model/ReportSettingsTemplateConfig.php @@ -26,6 +26,26 @@ class ReportSettingsTemplateConfig extends BaseModel */ protected $netRateSchemes; + /** + * @var bool + */ + protected $calculateInternalMatches; + + /** + * @var bool + */ + protected $includePreTranslatedStrings; + + /** + * @var bool + */ + protected $excludeApprovalsForEditedTranslations; + + /** + * @var bool + */ + protected $preTranslatedStringsCategorizationAdjustment; + public function __construct(array $data = []) { parent::__construct($data); @@ -35,6 +55,14 @@ public function __construct(array $data = []) return new IndividualRates($individualRates); }, $this->getDataProperty('individualRates') ?? []); $this->netRateSchemes = new NetRateSchemes($this->getDataProperty('netRateSchemes') ?? []); + $this->calculateInternalMatches = (bool)$this->getDataProperty('calculateInternalMatches'); + $this->includePreTranslatedStrings = (bool)$this->getDataProperty('includePreTranslatedStrings'); + $this->excludeApprovalsForEditedTranslations = (bool)$this->getDataProperty( + 'excludeApprovalsForEditedTranslations' + ); + $this->preTranslatedStringsCategorizationAdjustment = (bool)$this->getDataProperty( + 'preTranslatedStringsCategorizationAdjustment' + ); } public function getBaseRates(): BaseRates @@ -85,6 +113,47 @@ public function setNetRateSchemes(NetRateSchemes $netRateSchemes): void $this->netRateSchemes = $netRateSchemes; } + public function getCalculateInternalMatches(): bool + { + return $this->calculateInternalMatches; + } + + public function setCalculateInternalMatches(bool $calculateInternalMatches): void + { + $this->calculateInternalMatches = $calculateInternalMatches; + } + + public function getIncludePreTranslatedStrings(): bool + { + return $this->includePreTranslatedStrings; + } + + public function setIncludePreTranslatedStrings(bool $includePreTranslatedStrings): void + { + $this->includePreTranslatedStrings = $includePreTranslatedStrings; + } + + public function getExcludeApprovalsForEditedTranslations(): bool + { + return $this->excludeApprovalsForEditedTranslations; + } + + public function setExcludeApprovalsForEditedTranslations(bool $excludeApprovalsForEditedTranslations): void + { + $this->excludeApprovalsForEditedTranslations = $excludeApprovalsForEditedTranslations; + } + + public function getPreTranslatedStringsCategorizationAdjustment(): bool + { + return $this->preTranslatedStringsCategorizationAdjustment; + } + + public function setPreTranslatedStringsCategorizationAdjustment( + bool $preTranslatedStringsCategorizationAdjustment + ): void { + $this->preTranslatedStringsCategorizationAdjustment = $preTranslatedStringsCategorizationAdjustment; + } + public function toArray(): array { return [ @@ -93,6 +162,10 @@ public function toArray(): array return $individualRate->toArray(); }, $this->individualRates), 'netRateSchemes' => $this->netRateSchemes->toArray(), + 'calculateInternalMatches' => $this->calculateInternalMatches, + 'includePreTranslatedStrings' => $this->includePreTranslatedStrings, + 'excludeApprovalsForEditedTranslations' => $this->excludeApprovalsForEditedTranslations, + 'preTranslatedStringsCategorizationAdjustment' => $this->preTranslatedStringsCategorizationAdjustment, ]; } } diff --git a/src/CrowdinApiClient/Model/UserReportSettingsTemplate.php b/src/CrowdinApiClient/Model/UserReportSettingsTemplate.php new file mode 100644 index 00000000..c2bb9fb1 --- /dev/null +++ b/src/CrowdinApiClient/Model/UserReportSettingsTemplate.php @@ -0,0 +1,46 @@ +id = (int)$this->getDataProperty('id'); + $this->name = (string)$this->getDataProperty('name'); + $this->currency = (string)$this->getDataProperty('currency'); + $this->unit = (string)$this->getDataProperty('unit'); + $this->config = new ReportSettingsTemplateConfig($this->getDataProperty('config') ?? []); + $this->createdAt = (string)$this->getDataProperty('createdAt'); + $this->updatedAt = $this->getDataProperty('updatedAt') ? (string)$this->getDataProperty('updatedAt') : null; + } + + public function getConfig(): ReportSettingsTemplateConfig + { + return $this->config; + } + + /** + * @param ReportSettingsTemplateConfig $config + */ + public function setConfig($config): void + { + $this->config = $config; + } +} diff --git a/tests/CrowdinApiClient/Api/UserApiTest.php b/tests/CrowdinApiClient/Api/UserApiTest.php index 263b547b..4597591c 100644 --- a/tests/CrowdinApiClient/Api/UserApiTest.php +++ b/tests/CrowdinApiClient/Api/UserApiTest.php @@ -2,9 +2,14 @@ namespace CrowdinApiClient\Tests\Api; +use CrowdinApiClient\Model\HourlyReportSettingsTemplateConfig; +use CrowdinApiClient\Model\HourlyUserReportSettingsTemplate; use CrowdinApiClient\Model\ProjectMember; use CrowdinApiClient\Model\ProjectMemberAddedStatistics; +use CrowdinApiClient\Model\ReportSettingsTemplateConfig; use CrowdinApiClient\Model\User; +use CrowdinApiClient\Model\UserReportSettingsTemplate; +use CrowdinApiClient\ModelCollection; class UserApiTest extends AbstractTestApi { @@ -264,7 +269,7 @@ public function testReplaceProjectMemberPermissions(): void 'name' => 'translator', 'permissions' => [ 'allLanguages' => true, - 'languageAccess' => [] + 'languageAccess' => [], ], ]; @@ -285,7 +290,7 @@ public function testReplaceProjectMemberPermissions(): void 'name' => 'translator', 'permissions' => [ 'allLanguages' => true, - 'languageAccess' => [] + 'languageAccess' => [], ], ], 'avatarUrl' => '', @@ -310,4 +315,450 @@ public function testDeleteMemberFromProject(): void $this->crowdin->user->deleteMemberFromProject(1, 1); } + + public function listReportsDataProvider(): array + { + $pagination = [ + 'offset' => 0, + 'limit' => 25, + ]; + + return [ + 'userReportSettingsTemplate' => [ + 'requestData' => [ + 'data' => [ + [ + 'data' => [ + 'id' => 1, + 'name' => 'Default template', + 'currency' => 'USD', + 'unit' => 'words', + 'config' => [ + 'baseRates' => [ + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + 'individualRates' => [ + [ + 'languageIds' => ['uk'], + 'userIds' => [], + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + ], + 'netRateSchemes' => [ + 'tmMatch' => [ + [ + 'matchType' => '100', + 'price' => 0.1, + ], + ], + 'mtMatch' => [ + [ + 'matchType' => '100-82', + 'price' => 0.1, + ], + ], + 'aiMatch' => [ + [ + 'matchType' => '100-74', + 'price' => 0.1, + ], + ], + 'suggestionMatch' => [ + [ + 'matchType' => 'perfect', + 'price' => 0.1, + ], + ], + ], + 'calculateInternalMatches' => false, + 'includePreTranslatedStrings' => false, + 'excludeApprovalsForEditedTranslations' => false, + 'preTranslatedStringsCategorizationAdjustment' => false, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:54+00:00', + ], + ], + ], + 'pagination' => $pagination, + ], + 'className' => UserReportSettingsTemplate::class, + 'configClassName' => ReportSettingsTemplateConfig::class, + ], + 'hourlyUserReportSettingsTemplate' => [ + 'requestData' => [ + 'data' => [ + [ + 'data' => [ + 'id' => 12, + 'name' => 'Hourly template', + 'currency' => 'USD', + 'unit' => 'hours', + 'config' => [ + 'baseRates' => [ + 'hourly' => 50.0, + ], + 'individualRates' => [ + [ + 'languageIds' => ['uk'], + 'userIds' => [8], + 'hourly' => 75.0, + ], + ], + ], + 'createdAt' => '2025-01-23T15:23:11+00:00', + 'updatedAt' => '2025-01-23T15:35:49+00:00', + ], + ], + ], + 'pagination' => $pagination, + ], + 'className' => HourlyUserReportSettingsTemplate::class, + 'configClassName' => HourlyReportSettingsTemplateConfig::class, + ], + ]; + } + + /** + * @dataProvider listReportsDataProvider + */ + public function testListReportsSettingsTemplates( + array $requestData, + string $className, + string $configClassName + ): void { + $this->mockRequestGet( + '/users/1/reports/settings-templates?limit=25&offset=0', + json_encode($requestData) + ); + + $templates = $this->crowdin->user->listReportSettingsTemplates(1, ['limit' => 25, 'offset' => 0]); + $data = $requestData['data'][0]['data']; + + $this->assertInstanceOf(ModelCollection::class, $templates); + $this->assertCount(1, $templates); + $this->assertInstanceOf($className, $templates[0]); + $this->assertEquals($data['id'], $templates[0]->getId()); + $this->assertEquals($data['name'], $templates[0]->getName()); + $this->assertEquals($data['currency'], $templates[0]->getCurrency()); + $this->assertEquals($data['unit'], $templates[0]->getUnit()); + $this->assertInstanceOf($configClassName, $templates[0]->getConfig()); + } + + public function testCreateReportSettingsTemplate(): void + { + $this->mockRequestPost( + '/users/1/reports/settings-templates', + json_encode([ + 'name' => 'Default template', + 'currency' => 'USD', + 'unit' => 'words', + 'config' => [ + 'baseRates' => [ + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + 'individualRates' => [], + 'netRateSchemes' => [ + 'tmMatch' => [], + 'mtMatch' => [], + 'aiMatch' => [], + 'suggestionMatch' => [], + ], + ], + ]), + json_encode([ + 'data' => [ + 'id' => 1, + 'name' => 'Default template', + 'currency' => 'USD', + 'unit' => 'words', + 'config' => [ + 'baseRates' => [ + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + 'individualRates' => [], + 'netRateSchemes' => [ + 'tmMatch' => [], + 'mtMatch' => [], + 'aiMatch' => [], + 'suggestionMatch' => [], + ], + ], + 'isPublic' => false, + 'isGlobal' => false, + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => null, + ], + ]) + ); + + $params = [ + 'name' => 'Default template', + 'currency' => 'USD', + 'unit' => 'words', + 'config' => [ + 'baseRates' => [ + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + 'individualRates' => [], + 'netRateSchemes' => [ + 'tmMatch' => [], + 'mtMatch' => [], + 'aiMatch' => [], + 'suggestionMatch' => [], + ], + ], + ]; + + $template = $this->crowdin->user->createReportSettingsTemplate(1, $params); + + $this->assertInstanceOf(UserReportSettingsTemplate::class, $template); + $this->assertEquals(1, $template->getId()); + $this->assertEquals('Default template', $template->getName()); + $this->assertEquals('USD', $template->getCurrency()); + } + + public function getReportSettingsTemplateDataProvider(): array + { + return [ + 'userReportSettingsTemplate' => [ + 'requestData' => [ + 'data' => [ + 'id' => 1, + 'name' => 'Default template', + 'currency' => 'USD', + 'unit' => 'words', + 'config' => [ + 'baseRates' => [ + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + 'individualRates' => [ + [ + 'languageIds' => ['uk'], + 'userIds' => [], + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + ], + 'netRateSchemes' => [ + 'tmMatch' => [ + [ + 'matchType' => '100', + 'price' => 0.1, + ], + ], + 'mtMatch' => [ + [ + 'matchType' => '100-82', + 'price' => 0.1, + ], + ], + 'aiMatch' => [ + [ + 'matchType' => '100-74', + 'price' => 0.1, + ], + ], + 'suggestionMatch' => [ + [ + 'matchType' => 'perfect', + 'price' => 0.1, + ], + ], + ], + 'calculateInternalMatches' => false, + 'includePreTranslatedStrings' => false, + 'excludeApprovalsForEditedTranslations' => false, + 'preTranslatedStringsCategorizationAdjustment' => false, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:54+00:00', + ], + ], + 'className' => UserReportSettingsTemplate::class, + 'configClassName' => ReportSettingsTemplateConfig::class, + ], + 'hourlyUserReportSettingsTemplate' => [ + 'requestData' => [ + 'data' => [ + 'id' => 12, + 'name' => 'Hourly template', + 'currency' => 'USD', + 'unit' => 'hours', + 'config' => [ + 'baseRates' => [ + 'hourly' => 50.0, + ], + 'individualRates' => [ + [ + 'languageIds' => ['uk'], + 'userIds' => [8], + 'hourly' => 75.0, + ], + ], + ], + 'createdAt' => '2025-01-23T15:23:11+00:00', + 'updatedAt' => '2025-01-23T15:35:49+00:00', + ], + ], + 'className' => HourlyUserReportSettingsTemplate::class, + 'configClassName' => HourlyReportSettingsTemplateConfig::class, + ], + ]; + } + + /** + * @dataProvider getReportSettingsTemplateDataProvider + */ + public function testGetReportSettingsTemplate(array $requestData, string $className, string $configClassName): void + { + $this->mockRequestGet( + '/users/1/reports/settings-templates/1', + json_encode($requestData) + ); + + $template = $this->crowdin->user->getReportSettingsTemplate(1, 1); + + $this->assertInstanceOf($className, $template); + $this->assertEquals($requestData['data']['id'], $template->getId()); + $this->assertEquals($requestData['data']['name'], $template->getName()); + $this->assertEquals($requestData['data']['currency'], $template->getCurrency()); + $this->assertInstanceOf($configClassName, $template->getConfig()); + } + + public function testDeleteReportSettingsTemplate(): void + { + $this->mockRequestDelete('/users/1/reports/settings-templates/1'); + + $this->crowdin->user->deleteReportSettingsTemplate(1, 1); + } + + public function testUpdateReportSettingsTemplate(): void + { + $this->mockRequestPatch( + '/users/1/reports/settings-templates/1', + json_encode([ + 'data' => [ + 'id' => 1, + 'name' => 'Updated template name', + 'currency' => 'EUR', + 'unit' => 'words', + 'config' => [ + 'baseRates' => [ + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + 'individualRates' => [ + [ + 'languageIds' => ['uk'], + 'userIds' => [], + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + ], + 'netRateSchemes' => [ + 'tmMatch' => [ + [ + 'matchType' => '100', + 'price' => 0.1, + ], + ], + 'mtMatch' => [ + [ + 'matchType' => '100-82', + 'price' => 0.1, + ], + ], + 'aiMatch' => [ + [ + 'matchType' => '100-74', + 'price' => 0.1, + ], + ], + 'suggestionMatch' => [ + [ + 'matchType' => 'perfect', + 'price' => 0.1, + ], + ], + ], + 'calculateInternalMatches' => false, + 'includePreTranslatedStrings' => false, + 'excludeApprovalsForEditedTranslations' => false, + 'preTranslatedStringsCategorizationAdjustment' => false, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:54+00:00', + ], + ]) + ); + + $template = new UserReportSettingsTemplate([ + 'id' => 1, + 'name' => 'Default template', + 'currency' => 'USD', + 'unit' => 'words', + 'config' => [ + 'baseRates' => [ + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + 'individualRates' => [ + [ + 'languageIds' => ['uk'], + 'userIds' => [], + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + ], + 'netRateSchemes' => [ + 'tmMatch' => [ + [ + 'matchType' => '100', + 'price' => 0.1, + ], + ], + 'mtMatch' => [ + [ + 'matchType' => '100-82', + 'price' => 0.1, + ], + ], + 'aiMatch' => [ + [ + 'matchType' => '100-74', + 'price' => 0.1, + ], + ], + 'suggestionMatch' => [ + [ + 'matchType' => 'perfect', + 'price' => 0.1, + ], + ], + ], + 'calculateInternalMatches' => false, + 'includePreTranslatedStrings' => false, + 'excludeApprovalsForEditedTranslations' => false, + 'preTranslatedStringsCategorizationAdjustment' => false, + ], + 'createdAt' => '2019-09-23T11:26:54+00:00', + 'updatedAt' => '2019-09-23T11:26:54+00:00', + ]); + $template->setName('Updated template name'); + $template->setCurrency('EUR'); + + $result = $this->crowdin->user->updateReportSettingsTemplate(1, $template); + + $this->assertInstanceOf(UserReportSettingsTemplate::class, $result); + $this->assertEquals(1, $result->getId()); + $this->assertEquals('Updated template name', $result->getName()); + $this->assertEquals('EUR', $result->getCurrency()); + } } diff --git a/tests/CrowdinApiClient/Model/HourlyBaseRatesTest.php b/tests/CrowdinApiClient/Model/HourlyBaseRatesTest.php new file mode 100644 index 00000000..d54e6302 --- /dev/null +++ b/tests/CrowdinApiClient/Model/HourlyBaseRatesTest.php @@ -0,0 +1,35 @@ + 0.1, + ]; + + public function testLoadData(): void + { + $hourlyBaseRates = new HourlyBaseRates($this->data); + $this->assertEquals($this->data['hourly'], $hourlyBaseRates->getHourly()); + } + + public function testSetData(): void + { + $hourlyBaseRates = new HourlyBaseRates($this->data); + $hourlyBaseRates->setHourly(0.2); + + $this->assertEquals(0.2, $hourlyBaseRates->getHourly()); + } + + public function testToArray(): void + { + $hourlyBaseRates = new HourlyBaseRates($this->data); + $this->assertEquals($this->data, $hourlyBaseRates->toArray()); + } +} diff --git a/tests/CrowdinApiClient/Model/HourlyIndividualRatesTest.php b/tests/CrowdinApiClient/Model/HourlyIndividualRatesTest.php new file mode 100644 index 00000000..e772e776 --- /dev/null +++ b/tests/CrowdinApiClient/Model/HourlyIndividualRatesTest.php @@ -0,0 +1,107 @@ + ['en', 'uk', 'de'], + 'userIds' => [1, 2, 3], + 'hourly' => 0.1, + ]; + + public function testLoadData(): void + { + $individualRates = new HourlyIndividualRates($this->data); + $this->assertEquals($this->data['languageIds'], $individualRates->getLanguageIds()); + $this->assertEquals($this->data['userIds'], $individualRates->getUserIds()); + $this->assertEquals($this->data['hourly'], $individualRates->getHourly()); + } + + public function testSetData(): void + { + $languageIds = ['en', 'uk', 'de', 'fr']; + $userIds = [8]; + $hourly = 0.2; + + $individualRates = new HourlyIndividualRates($this->data); + $individualRates->setLanguageIds($languageIds); + $individualRates->setUserIds($userIds); + $individualRates->setHourly($hourly); + + $this->assertEquals($languageIds, $individualRates->getLanguageIds()); + $this->assertEquals($userIds, $individualRates->getUserIds()); + $this->assertEquals($hourly, $individualRates->getHourly()); + } + + public function testToArray(): void + { + $individualRates = new HourlyIndividualRates($this->data); + $result = $individualRates->toArray(); + + $this->assertArrayHasKey('languageIds', $result); + $this->assertArrayHasKey('userIds', $result); + $this->assertArrayHasKey('hourly', $result); + $this->assertEquals($this->data['languageIds'], $result['languageIds']); + $this->assertEquals($this->data['userIds'], $result['userIds']); + $this->assertEquals($this->data['hourly'], $result['hourly']); + } + + public function languageIdsExceptionDataProvider(): array + { + return [ + 'empty' => [ + 'languageIds' => [], + 'exceptionMessage' => 'Argument "languageIds" cannot be empty', + ], + 'invalidType' => [ + 'languageIds' => [1, 2, 3], + 'exceptionMessage' => 'Argument "languageIds" must be an array of strings', + ], + ]; + } + + /** + * @dataProvider languageIdsExceptionDataProvider + */ + public function testSetLanguageIdsException(array $languageIds, string $exceptionMessage): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage($exceptionMessage); + + $individualRates = new HourlyIndividualRates(); + $individualRates->setLanguageIds($languageIds); + } + + public function userIdsExceptionDataProvider(): array + { + return [ + 'empty' => [ + 'userIds' => [], + 'exceptionMessage' => 'Argument "userIds" cannot be empty', + ], + 'invalidType' => [ + 'userIds' => ['123'], + 'exceptionMessage' => 'Argument "userIds" must be an array of integers', + ] + ]; + } + + /** + * @dataProvider userIdsExceptionDataProvider + */ + public function testSetUserIdsException(array $userIds, string $exceptionMessage): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage($exceptionMessage); + + $individualRates = new HourlyIndividualRates(); + $individualRates->setUserIds($userIds); + } +} diff --git a/tests/CrowdinApiClient/Model/HourlyReportSettingsTemplateConfigTest.php b/tests/CrowdinApiClient/Model/HourlyReportSettingsTemplateConfigTest.php new file mode 100644 index 00000000..3bd23f01 --- /dev/null +++ b/tests/CrowdinApiClient/Model/HourlyReportSettingsTemplateConfigTest.php @@ -0,0 +1,104 @@ + [ + 'hourly' => 0.1, + ], + 'individualRates' => [ + [ + 'languageIds' => ['uk'], + 'userIds' => [8], + 'hourly' => 0.1, + ], + ], + ]; + + public function testLoadData(): void + { + $reportSettingsTemplateConfig = new HourlyReportSettingsTemplateConfig($this->data); + + $this->assertEquals( + $this->data['baseRates'], + $reportSettingsTemplateConfig->getBaseRates()->toArray() + ); + $this->assertEquals( + $this->data['individualRates'], + array_map(static function (HourlyIndividualRates $individualRates): array { + return $individualRates->toArray(); + }, $reportSettingsTemplateConfig->getIndividualRates()) + ); + } + + public function testSetData(): void + { + $baseRates = new HourlyBaseRates(['hourly' => 0.2]); + $individualRates = [ + new HourlyIndividualRates([ + 'languageIds' => ['uk', 'en', 'jp'], + 'userIds' => [8], + 'hourly' => 0.3, + ]), + ]; + + $reportSettingsTemplateConfig = new HourlyReportSettingsTemplateConfig($this->data); + $reportSettingsTemplateConfig->setBaseRates($baseRates); + $reportSettingsTemplateConfig->setIndividualRates($individualRates); + + $this->assertEquals( + $baseRates->toArray(), + $reportSettingsTemplateConfig->getBaseRates()->toArray() + ); + $this->assertEquals( + array_map(static function (HourlyIndividualRates $individualRates): array { + return $individualRates->toArray(); + }, $individualRates), + array_map(static function (HourlyIndividualRates $individualRates): array { + return $individualRates->toArray(); + }, $reportSettingsTemplateConfig->getIndividualRates()) + ); + } + + public function individualRatesExceptionDataProvider(): array + { + return [ + 'empty' => [ + 'individualRates' => [], + 'exceptionMessage' => 'Argument "individualRates" cannot be empty', + ], + 'invalidType' => [ + 'individualRates' => [ + [], + ], + 'exceptionMessage' => 'Argument "individualRates" must contain only HourlyIndividualRates objects', + ], + ]; + } + + /** + * @dataProvider individualRatesExceptionDataProvider + */ + public function testSetIndividualRatesException(array $individualRates, string $exceptionMessage): void + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage($exceptionMessage); + + (new HourlyReportSettingsTemplateConfig($this->data))->setIndividualRates($individualRates); + } + + public function testToArray(): void + { + $this->assertSame($this->data, (new HourlyReportSettingsTemplateConfig($this->data))->toArray()); + } +} diff --git a/tests/CrowdinApiClient/Model/HourlyUserReportSettingsTemplateTest.php b/tests/CrowdinApiClient/Model/HourlyUserReportSettingsTemplateTest.php new file mode 100644 index 00000000..d15d13ea --- /dev/null +++ b/tests/CrowdinApiClient/Model/HourlyUserReportSettingsTemplateTest.php @@ -0,0 +1,97 @@ + 12, + 'name' => 'Hourly template', + 'currency' => 'USD', + 'unit' => 'hours', + 'config' => [ + 'baseRates' => [ + 'hourly' => 50.0, + ], + 'individualRates' => [ + [ + 'languageIds' => ['uk'], + 'userIds' => [8], + 'hourly' => 75.0, + ], + ], + ], + 'createdAt' => '2025-01-23T15:23:11+00:00', + 'updatedAt' => '2025-01-23T15:35:49+00:00', + ]; + + public function testLoadData(): void + { + $template = new HourlyUserReportSettingsTemplate($this->data); + + $this->assertEquals($this->data['id'], $template->getId()); + $this->assertEquals($this->data['name'], $template->getName()); + $this->assertEquals($this->data['currency'], $template->getCurrency()); + $this->assertEquals($this->data['unit'], $template->getUnit()); + $this->assertInstanceOf(HourlyReportSettingsTemplateConfig::class, $template->getConfig()); + $this->assertEquals( + $this->data['config']['baseRates']['hourly'], + $template->getConfig()->getBaseRates()->getHourly() + ); + $this->assertEquals($this->data['createdAt'], $template->getCreatedAt()); + $this->assertEquals($this->data['updatedAt'], $template->getUpdatedAt()); + } + + public function testSetData(): void + { + $template = new HourlyUserReportSettingsTemplate($this->data); + + $name = 'New name'; + $currency = 'UAH'; + $unit = 'hours'; + $hourly = 100.0; + + $config = $template->getConfig(); + $config->setBaseRates(new HourlyBaseRates(['hourly' => $hourly])); + + $template->setName($name); + $template->setCurrency($currency); + $template->setUnit($unit); + $template->setConfig($config); + + $this->assertEquals($name, $template->getName()); + $this->assertEquals($currency, $template->getCurrency()); + $this->assertEquals($unit, $template->getUnit()); + $this->assertEquals($hourly, $template->getConfig()->getBaseRates()->getHourly()); + } + + public function testSetInvalidCurrency(): void + { + $this->expectException(InvalidArgumentException::class); + + $template = new HourlyUserReportSettingsTemplate($this->data); + $template->setCurrency('INVALID'); + } + + public function testSetInvalidUnit(): void + { + $this->expectException(InvalidArgumentException::class); + + $template = new HourlyUserReportSettingsTemplate($this->data); + $template->setUnit(Report::UNIT_WORDS); + } + + public function testToArray(): void + { + $this->assertEquals($this->data, (new HourlyUserReportSettingsTemplate($this->data))->toArray()); + } +} diff --git a/tests/CrowdinApiClient/Model/ReportSettingsTemplateConfigTest.php b/tests/CrowdinApiClient/Model/ReportSettingsTemplateConfigTest.php index 2e682caa..b3c7d6ba 100644 --- a/tests/CrowdinApiClient/Model/ReportSettingsTemplateConfigTest.php +++ b/tests/CrowdinApiClient/Model/ReportSettingsTemplateConfigTest.php @@ -56,17 +56,45 @@ class ReportSettingsTemplateConfigTest extends TestCase ], ], ], + 'calculateInternalMatches' => true, + 'includePreTranslatedStrings' => false, + 'excludeApprovalsForEditedTranslations' => true, + 'preTranslatedStringsCategorizationAdjustment' => false, ]; - /** - * @var ReportSettingsTemplateConfig - */ - public $reportSettingsTemplateConfig; - public function testLoadData(): void { - $this->reportSettingsTemplateConfig = new ReportSettingsTemplateConfig($this->data); - $this->checkData(); + $reportSettingsTemplateConfig = new ReportSettingsTemplateConfig($this->data); + $this->assertEquals( + $this->data['baseRates'], + $reportSettingsTemplateConfig->getBaseRates()->toArray() + ); + $this->assertEquals( + $this->data['individualRates'], + array_map(static function (IndividualRates $individualRates): array { + return $individualRates->toArray(); + }, $reportSettingsTemplateConfig->getIndividualRates()) + ); + $this->assertEquals( + $this->data['netRateSchemes'], + $reportSettingsTemplateConfig->getNetRateSchemes()->toArray() + ); + $this->assertEquals( + $this->data['calculateInternalMatches'], + $reportSettingsTemplateConfig->getCalculateInternalMatches() + ); + $this->assertEquals( + $this->data['includePreTranslatedStrings'], + $reportSettingsTemplateConfig->getIncludePreTranslatedStrings() + ); + $this->assertEquals( + $this->data['excludeApprovalsForEditedTranslations'], + $reportSettingsTemplateConfig->getExcludeApprovalsForEditedTranslations() + ); + $this->assertEquals( + $this->data['preTranslatedStringsCategorizationAdjustment'], + $reportSettingsTemplateConfig->getPreTranslatedStringsCategorizationAdjustment() + ); } /** @@ -74,46 +102,52 @@ public function testLoadData(): void */ public function testSetData(): void { - $this->reportSettingsTemplateConfig = new ReportSettingsTemplateConfig(); - $this->reportSettingsTemplateConfig->setBaseRates(new BaseRates($this->data['baseRates'])); - $this->reportSettingsTemplateConfig->setIndividualRates( + $reportSettingsTemplateConfig = new ReportSettingsTemplateConfig(); + $reportSettingsTemplateConfig->setBaseRates(new BaseRates($this->data['baseRates'])); + $reportSettingsTemplateConfig->setIndividualRates( array_map(static function (array $individualRates): IndividualRates { return new IndividualRates($individualRates); }, $this->data['individualRates']) ); - $this->reportSettingsTemplateConfig->setNetRateSchemes(new NetRateSchemes($this->data['netRateSchemes'])); + $reportSettingsTemplateConfig->setNetRateSchemes(new NetRateSchemes($this->data['netRateSchemes'])); + $reportSettingsTemplateConfig->setCalculateInternalMatches($this->data['calculateInternalMatches']); + $reportSettingsTemplateConfig->setIncludePreTranslatedStrings($this->data['includePreTranslatedStrings']); + $reportSettingsTemplateConfig->setExcludeApprovalsForEditedTranslations( + $this->data['excludeApprovalsForEditedTranslations'] + ); + $reportSettingsTemplateConfig->setPreTranslatedStringsCategorizationAdjustment( + $this->data['preTranslatedStringsCategorizationAdjustment'] + ); $this->assertEquals( $this->data['baseRates'], - $this->reportSettingsTemplateConfig->getBaseRates()->toArray() + $reportSettingsTemplateConfig->getBaseRates()->toArray() ); $this->assertEquals( $this->data['individualRates'], array_map(static function (IndividualRates $individualRates): array { return $individualRates->toArray(); - }, $this->reportSettingsTemplateConfig->getIndividualRates()) + }, $reportSettingsTemplateConfig->getIndividualRates()) ); $this->assertEquals( $this->data['netRateSchemes'], - $this->reportSettingsTemplateConfig->getNetRateSchemes()->toArray() + $reportSettingsTemplateConfig->getNetRateSchemes()->toArray() ); - } - - public function checkData(): void - { $this->assertEquals( - $this->data['baseRates'], - $this->reportSettingsTemplateConfig->getBaseRates()->toArray() + $this->data['calculateInternalMatches'], + $reportSettingsTemplateConfig->getCalculateInternalMatches() ); $this->assertEquals( - $this->data['individualRates'], - array_map(static function (IndividualRates $individualRates): array { - return $individualRates->toArray(); - }, $this->reportSettingsTemplateConfig->getIndividualRates()) + $this->data['includePreTranslatedStrings'], + $reportSettingsTemplateConfig->getIncludePreTranslatedStrings() ); $this->assertEquals( - $this->data['netRateSchemes'], - $this->reportSettingsTemplateConfig->getNetRateSchemes()->toArray() + $this->data['excludeApprovalsForEditedTranslations'], + $reportSettingsTemplateConfig->getExcludeApprovalsForEditedTranslations() + ); + $this->assertEquals( + $this->data['preTranslatedStringsCategorizationAdjustment'], + $reportSettingsTemplateConfig->getPreTranslatedStringsCategorizationAdjustment() ); } diff --git a/tests/CrowdinApiClient/Model/ReportSettingsTemplateTest.php b/tests/CrowdinApiClient/Model/ReportSettingsTemplateTest.php index 16bdff0d..c17f800d 100644 --- a/tests/CrowdinApiClient/Model/ReportSettingsTemplateTest.php +++ b/tests/CrowdinApiClient/Model/ReportSettingsTemplateTest.php @@ -59,6 +59,10 @@ class ReportSettingsTemplateTest extends TestCase ], ], ], + 'calculateInternalMatches' => true, + 'includePreTranslatedStrings' => true, + 'excludeApprovalsForEditedTranslations' => true, + 'preTranslatedStringsCategorizationAdjustment' => true, ], 'isPublic' => true, 'isGlobal' => true, @@ -74,7 +78,15 @@ class ReportSettingsTemplateTest extends TestCase public function testLoadData(): void { $this->reportSettingsTemplate = new ReportSettingsTemplate($this->data); - $this->checkData(); + $this->assertEquals($this->data['id'], $this->reportSettingsTemplate->getId()); + $this->assertEquals($this->data['name'], $this->reportSettingsTemplate->getName()); + $this->assertEquals($this->data['currency'], $this->reportSettingsTemplate->getCurrency()); + $this->assertEquals($this->data['unit'], $this->reportSettingsTemplate->getUnit()); + $this->assertEquals($this->data['config'], $this->reportSettingsTemplate->getConfig()->toArray()); + $this->assertEquals($this->data['isPublic'], $this->reportSettingsTemplate->getIsPublic()); + $this->assertEquals($this->data['isGlobal'], $this->reportSettingsTemplate->getIsGlobal()); + $this->assertEquals($this->data['createdAt'], $this->reportSettingsTemplate->getCreatedAt()); + $this->assertEquals($this->data['updatedAt'], $this->reportSettingsTemplate->getUpdatedAt()); } /** @@ -96,19 +108,6 @@ public function testSetData(): void $this->assertEquals($this->data['isPublic'], $this->reportSettingsTemplate->getIsPublic()); } - public function checkData(): void - { - $this->assertEquals($this->data['id'], $this->reportSettingsTemplate->getId()); - $this->assertEquals($this->data['name'], $this->reportSettingsTemplate->getName()); - $this->assertEquals($this->data['currency'], $this->reportSettingsTemplate->getCurrency()); - $this->assertEquals($this->data['unit'], $this->reportSettingsTemplate->getUnit()); - $this->assertEquals($this->data['config'], $this->reportSettingsTemplate->getConfig()->toArray()); - $this->assertEquals($this->data['isPublic'], $this->reportSettingsTemplate->getIsPublic()); - $this->assertEquals($this->data['isGlobal'], $this->reportSettingsTemplate->getIsGlobal()); - $this->assertEquals($this->data['createdAt'], $this->reportSettingsTemplate->getCreatedAt()); - $this->assertEquals($this->data['updatedAt'], $this->reportSettingsTemplate->getUpdatedAt()); - } - public function testSetCurrencyException(): void { $this->expectException(InvalidArgumentException::class); diff --git a/tests/CrowdinApiClient/Model/UserReportSettingsTemplateTest.php b/tests/CrowdinApiClient/Model/UserReportSettingsTemplateTest.php new file mode 100644 index 00000000..5fc5869b --- /dev/null +++ b/tests/CrowdinApiClient/Model/UserReportSettingsTemplateTest.php @@ -0,0 +1,123 @@ + 12, + 'name' => 'Default template', + 'currency' => 'UAH', + 'unit' => 'words', + 'config' => [ + 'baseRates' => [ + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + 'individualRates' => [ + [ + 'languageIds' => ['uk'], + 'userIds' => [8], + 'fullTranslation' => 0.1, + 'proofread' => 0.12, + ], + ], + 'netRateSchemes' => [ + 'tmMatch' => [ + [ + 'matchType' => 'perfect', + 'price' => 0.1, + ], + [ + 'matchType' => '100', + 'price' => 0.2, + ], + ], + 'mtMatch' => [ + [ + 'matchType' => '100', + 'price' => 0.1, + ], + ], + 'aiMatch' => [ + [ + 'matchType' => '100', + 'price' => 0.1, + ], + ], + 'suggestionMatch' => [ + [ + 'matchType' => '100', + 'price' => 0.1, + ], + ], + ], + 'calculateInternalMatches' => true, + 'includePreTranslatedStrings' => true, + 'excludeApprovalsForEditedTranslations' => true, + 'preTranslatedStringsCategorizationAdjustment' => true, + ], + 'createdAt' => '2025-01-23T15:23:11+00:00', + 'updatedAt' => '2025-01-23T15:35:49+00:00', + ]; + + public function testLoadData(): void + { + $template = new UserReportSettingsTemplate($this->data); + + $this->assertEquals($this->data['id'], $template->getId()); + $this->assertEquals($this->data['name'], $template->getName()); + $this->assertEquals($this->data['currency'], $template->getCurrency()); + $this->assertEquals($this->data['unit'], $template->getUnit()); + $this->assertInstanceOf(ReportSettingsTemplateConfig::class, $template->getConfig()); + $this->assertEquals($this->data['config'], $template->getConfig()->toArray()); + $this->assertEquals($this->data['createdAt'], $template->getCreatedAt()); + $this->assertEquals($this->data['updatedAt'], $template->getUpdatedAt()); + } + + public function testSetData(): void + { + $template = new UserReportSettingsTemplate($this->data); + + $config = $template->getConfig(); + $config->setCalculateInternalMatches(false); + + $template->setName('New name'); + $template->setCurrency('GBP'); + $template->setUnit('strings'); + $template->setConfig($config); + + $this->assertEquals('New name', $template->getName()); + $this->assertEquals('GBP', $template->getCurrency()); + $this->assertEquals('strings', $template->getUnit()); + $this->assertFalse($template->getConfig()->getCalculateInternalMatches()); + } + + public function testSetInvalidCurrency(): void + { + $this->expectException(InvalidArgumentException::class); + + $template = new UserReportSettingsTemplate($this->data); + $template->setCurrency('INVALID'); + } + + public function testSetInvalidUnit(): void + { + $this->expectException(InvalidArgumentException::class); + + $template = new UserReportSettingsTemplate($this->data); + $template->setUnit('INVALID'); + } + + public function testToArray(): void + { + $this->assertEquals($this->data, (new UserReportSettingsTemplate($this->data))->toArray()); + } +}