diff --git a/CHANGELOG.md b/CHANGELOG.md index 45c1c3e..0796b43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ The format is based now on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [4.2.0] +- Added [multi-page document conversion](https://uploadcare.com/docs/transformations/document-conversion/#multipage-conversion). +- Added [Unsafe content detection](https://uploadcare.com/docs/unsafe-content/). +- `\Uploadcare\Group::getDatetimeStored` method is deprecated. + ## [4.1.1] - Retrieve the Metadata without additional requests when using `getMetadata`. - You can still get the fresh metadata for the file by calling `getMetadata` method from the `MetadataApiInterface`. diff --git a/README.md b/README.md index fce66ca..d1d2506 100644 --- a/README.md +++ b/README.md @@ -288,6 +288,29 @@ while (($status = $api->addons()->checkAwsRecognition($token)) !== 'done') { $recognitionData = $api->file()->fileInfo($file->getUuid())->getAppdata()->getAwsRekognitionDetectLabels(); // Instance of \Uploadcare\Interfaces\File\AppData\AwsRecognitionLabelsInterface ``` +### [Unsafe content detection](https://uploadcare.com/docs/unsafe-content/) + +To call unsafe content detection from the library: + +```php +$configuration = \Uploadcare\Configuration::create($_ENV['UPLOADCARE_PUBLIC_KEY'], $_ENV['UPLOADCARE_SECRET_KEY']); + +$api = new \Uploadcare\Api($configuration); +/** @var \Uploadcare\Interfaces\File\FileInfoInterface $file */ +$file = $api->file()->listFiles()->getResults()->first(); + +# Request recognition, get token to check status +$token = $api->addons()->requestAwsRecognitionModeration($file); +while (($status = $api->addons()->checkAwsRecognitionModeration($token)) !== 'done') { + \usleep(1000); + if ($status === 'error') { + throw new \Exception('Error in process'); + } +} + +$recognitionModerationData = $api->file()->fileInfo($file->getUuid())->getAppdata()->getAwsRekognitionDetectModerationLabels() // Instance of \Uploadcare\Interfaces\File\AppData\AwsModerationLabelInterface +``` + ### [Remove background](https://uploadcare.com/docs/remove-bg/) Remove background from image: @@ -347,8 +370,7 @@ After that, you can access group operation methods: ### `Uploadcare\Group` class -This class implements `Uploadcare\Interfaces\GroupInterface` aand has an additional `store()` method that applies the store operation to the group. Calls `GroupApi::store group`; - +This class implements `Uploadcare\Interfaces\GroupInterface`. The `getFiles()` method of the `Uploadcare\Group` object returns [FileCollection](#uploadcarefilecollection-class). ## Project operations @@ -373,7 +395,7 @@ Now, the `$projectInfo` variable contains the `Uploadcare\Interfaces\Response\Pr - `getPubKey()` — Project public key as string. - `isAutostoreEnabled()` — Returns `true` if the project files are stored automatically. -## Webhooks +## [Webhooks](https://uploadcare.com/docs/webhooks/) Call the webhook API: @@ -385,7 +407,7 @@ $webhookApi = (new \Uploadcare\Api($config))->webhook(); The methods are: - `listWebhooks()` — Returns a list of project webhooks as an instance of an `Uploadcare\WebhookCollection` class. Each element of this collection is an instance of a `Uploadcare\Webhook` class (see below); -- `createWebhook(string $targetUrl, bool $isActive = true, string $signingSecret = null, string $event = 'file.uploaded')` — Creates a new webhook for the event. Returns the `Uploadcare\Webhook` class. +- `createWebhook(string $targetUrl, bool $isActive = true, string $signingSecret = null, string $event = 'file.uploaded')` — Creates a new webhook for the event. Returns the `Uploadcare\Webhook` class. Event types described [here](https://uploadcare.com/docs/webhooks/#event-types) - `updateWebhook($id, array $parameters)` — Updates an existing webhook with these parameters. Parameters can be: - `target_url` — A target callback URL; - `event` — The only `file.uploaded` event is supported at the moment. @@ -435,6 +457,14 @@ Result will contain one of two objects: The `ConvertedItemInterface` will contain a UUID of converted document and token with conversion job ID. You can request the conversion job status with this ID (or the `ConvertedItemInterface` object itself): +You can also pass the `true` to the `setSaveInGroup` method to the Request object. + +```php +$request = (new \Uploadcare\Conversion\DocumentConversionRequest('pdf'))->setSaveInGroup(true); +``` + +In this case, the result of the document conversion will be stored in a group. See further details [here](https://uploadcare.com/docs/transformations/document-conversion/#multipage-conversion). + ```php $status = $convertor->documentJobStatus($result); // or $result->getToken() ``` diff --git a/api-samples/rest-api/get-addons-aws_rekognition_detect_moderation_labels-execute-status.php b/api-samples/rest-api/get-addons-aws_rekognition_detect_moderation_labels-execute-status.php new file mode 100644 index 0000000..6382f5f --- /dev/null +++ b/api-samples/rest-api/get-addons-aws_rekognition_detect_moderation_labels-execute-status.php @@ -0,0 +1,7 @@ +addons(); +$status = $api->checkAwsRecognitionModeration('request-id'); + +echo \sprintf('Recognition status: %s', $status); diff --git a/api-samples/rest-api/post-addons-aws_rekognition_detect_moderation_labels-execute.php b/api-samples/rest-api/post-addons-aws_rekognition_detect_moderation_labels-execute.php new file mode 100644 index 0000000..4b04657 --- /dev/null +++ b/api-samples/rest-api/post-addons-aws_rekognition_detect_moderation_labels-execute.php @@ -0,0 +1,7 @@ +addons(); +$resultKey = $api->requestAwsRecognitionModeration('1bac376c-aa7e-4356-861b-dd2657b5bfd2'); + +echo \sprintf('Recognition requested. Key is \'%s\'', $resultKey); diff --git a/api-samples/rest-api/post-webhooks.php b/api-samples/rest-api/post-webhooks.php index 72a47c0..ac2e10c 100644 --- a/api-samples/rest-api/post-webhooks.php +++ b/api-samples/rest-api/post-webhooks.php @@ -3,6 +3,6 @@ $configuration = Uploadcare\Configuration::create((string) $_ENV['UPLOADCARE_PUBLIC_KEY'], (string) $_ENV['UPLOADCARE_SECRET_KEY']); $api = (new Uploadcare\Api($configuration))->webhook(); -$result = $api->createWebhook('https://yourwebhook.com', true, 'sign-secret'); +$result = $api->createWebhook('https://yourwebhook.com', true, 'sign-secret', 'file.uploaded'); // The event can be any of `file.uploaded`, `file.info_updated`, `file.deleted`, `file.stored`, `file.infected` echo \sprintf('Webhook %s created', $result->getId()); diff --git a/api-samples/upload-api/post-from_url.php b/api-samples/upload-api/post-from_url.php index 210bd87..35e681e 100644 --- a/api-samples/upload-api/post-from_url.php +++ b/api-samples/upload-api/post-from_url.php @@ -3,7 +3,7 @@ $configuration = Uploadcare\Configuration::create((string) $_ENV['UPLOADCARE_PUBLIC_KEY'], (string) $_ENV['UPLOADCARE_SECRET_KEY']); $uploader = new Uploadcare\Uploader\Uploader($configuration); -$url = 'https://source.unsplash.com/random'; +$url = 'https://source.unsplash.com/featured'; $token = $uploader->fromUrl($url, null, null, 'auto', [ 'action' => 'upload from URL', // The "Action" is the metadata key 'checkDuplicates' => true, diff --git a/src/Apis/AddonsApi.php b/src/Apis/AddonsApi.php index d451486..4a952f1 100644 --- a/src/Apis/AddonsApi.php +++ b/src/Apis/AddonsApi.php @@ -7,6 +7,23 @@ class AddonsApi extends AbstractApi implements AddonsApiInterface { + public function requestAwsRecognitionModeration($id): string + { + $response = $this->request('POST', '/addons/aws_rekognition_detect_moderation_labels/execute/', [ + 'body' => ['target' => (string) $id], + ])->getBody()->getContents(); + + return $this->getResponseParameter($response, 'request_id'); + } + + public function checkAwsRecognitionModeration(string $id): string + { + $uri = \sprintf('/addons/aws_rekognition_detect_moderation_labels/execute/status/?request_id=%s', $id); + $response = $this->request('GET', $uri)->getBody()->getContents(); + + return $this->getResponseParameter($response, 'status'); + } + public function requestAwsRecognition($id): string { $response = $this->request('POST', '/addons/aws_rekognition_detect_labels/execute/', [ diff --git a/src/Apis/ConversionApi.php b/src/Apis/ConversionApi.php index c2e3e79..37278d0 100644 --- a/src/Apis/ConversionApi.php +++ b/src/Apis/ConversionApi.php @@ -254,7 +254,7 @@ private function requestDocumentConversion(array $conversionParams): BatchRespon } /** - * @param array $ids File ID's + * @param string[] $ids File ID's */ private function makeDocumentConversionUrl(array $ids, DocumentConversionRequestInterface $request): array { @@ -268,9 +268,14 @@ private function makeDocumentConversionUrl(array $ids, DocumentConversionRequest } } - return [ + $requestParameters = [ 'paths' => $patch, 'store' => $request->store(), ]; + if ($request->isSaveInGroup() === true) { + $requestParameters['save_in_group'] = true; + } + + return $requestParameters; } } diff --git a/src/Configuration.php b/src/Configuration.php index 4faf127..e7287d3 100644 --- a/src/Configuration.php +++ b/src/Configuration.php @@ -16,7 +16,7 @@ */ final class Configuration implements ConfigurationInterface { - public const LIBRARY_VERSION = 'v4.1.1'; + public const LIBRARY_VERSION = 'v4.2.0'; public const API_VERSION = '0.7'; public const API_BASE_URL = 'api.uploadcare.com'; public const USER_AGENT_TEMPLATE = 'PHPUploadcare/{lib-version}/{publicKey} (PHP/{lang-version})'; diff --git a/src/Conversion/DocumentConversionRequest.php b/src/Conversion/DocumentConversionRequest.php index 55209ec..c68ff1a 100644 --- a/src/Conversion/DocumentConversionRequest.php +++ b/src/Conversion/DocumentConversionRequest.php @@ -16,6 +16,7 @@ class DocumentConversionRequest implements DocumentConversionRequestInterface private bool $throwError = false; private bool $store = true; private ?int $pageNumber = null; + private bool $saveToGroup = false; public function __construct(string $targetFormat = 'pdf', bool $throwError = false, bool $store = true, ?int $pageNumber = null) { @@ -76,4 +77,16 @@ public function setPageNumber(?int $pageNumber): self return $this; } + + public function setSaveInGroup(bool $saveInGroup): self + { + $this->saveToGroup = $saveInGroup; + + return $this; + } + + public function isSaveInGroup(): bool + { + return $this->pageNumber !== null ? false : $this->saveToGroup; + } } diff --git a/src/Conversion/VideoEncodingRequest.php b/src/Conversion/VideoEncodingRequest.php index c2082ec..99f2499 100644 --- a/src/Conversion/VideoEncodingRequest.php +++ b/src/Conversion/VideoEncodingRequest.php @@ -208,4 +208,9 @@ private function checkTime(string $time): void throw new InvalidArgumentException(\sprintf('Time string \'%s\' not valid', $time)); } } + + public function isSaveInGroup(): bool + { + return false; + } } diff --git a/src/File/AppData.php b/src/File/AppData.php index f7d2889..b45cb88 100644 --- a/src/File/AppData.php +++ b/src/File/AppData.php @@ -3,6 +3,7 @@ namespace Uploadcare\File; use Uploadcare\File\AppData\AwsRecognitionLabels; +use Uploadcare\File\AppData\AwsRecognitionModerationLabels; use Uploadcare\File\AppData\ClamAvVirusScan; use Uploadcare\File\AppData\RemoveBg; use Uploadcare\Interfaces\File\AppDataInterface; @@ -11,6 +12,7 @@ final class AppData implements AppDataInterface, SerializableInterface { private ?AwsRecognitionLabels $awsRecognitionLabels = null; + private ?AwsRecognitionModerationLabels $awsRekognitionDetectModerationLabels = null; private ?ClamAvVirusScan $clamAvVirusScan = null; private ?RemoveBg $removeBg = null; @@ -18,11 +20,24 @@ public static function rules(): array { return [ 'awsRekognitionDetectLabels' => AwsRecognitionLabels::class, + 'awsRekognitionDetectModerationLabels' => AwsRecognitionModerationLabels::class, 'ucClamavVirusScan' => ClamAvVirusScan::class, 'removeBg' => RemoveBg::class, ]; } + public function getAwsRekognitionDetectModerationLabels(): ?AwsRecognitionModerationLabels + { + return $this->awsRekognitionDetectModerationLabels; + } + + public function setAwsRekognitionDetectModerationLabels(?AwsRecognitionModerationLabels $labels): self + { + $this->awsRekognitionDetectModerationLabels = $labels; + + return $this; + } + public function getAwsRekognitionDetectLabels(): ?AwsRecognitionLabels { return $this->awsRecognitionLabels; diff --git a/src/File/AppData/AbstractAwsLabels.php b/src/File/AppData/AbstractAwsLabels.php new file mode 100644 index 0000000..d7294db --- /dev/null +++ b/src/File/AppData/AbstractAwsLabels.php @@ -0,0 +1,46 @@ +version; + } + + public function setVersion(?string $version): self + { + $this->version = $version; + + return $this; + } + + public function getDatetimeCreated(): ?\DateTimeInterface + { + return $this->datetimeCreated; + } + + public function setDatetimeCreated(?\DateTimeInterface $datetimeCreated): self + { + $this->datetimeCreated = $datetimeCreated; + + return $this; + } + + public function getDatetimeUpdated(): ?\DateTimeInterface + { + return $this->datetimeUpdated; + } + + public function setDatetimeUpdated(?\DateTimeInterface $datetimeUpdated): self + { + $this->datetimeUpdated = $datetimeUpdated; + + return $this; + } +} diff --git a/src/File/AppData/AwsModerationLabel.php b/src/File/AppData/AwsModerationLabel.php new file mode 100644 index 0000000..688a82f --- /dev/null +++ b/src/File/AppData/AwsModerationLabel.php @@ -0,0 +1,58 @@ + 'float', + 'name' => 'string', + 'parentName' => 'string', + ]; + } + + public function getConfidence(): ?float + { + return $this->confidence; + } + + public function setConfidence(?float $confidence): self + { + $this->confidence = $confidence; + + return $this; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setName(?string $name): self + { + $this->name = $name; + + return $this; + } + + public function getParentName(): ?string + { + return $this->parentName; + } + + public function setParentName(?string $parentName): self + { + $this->parentName = $parentName; + + return $this; + } +} diff --git a/src/File/AppData/AwsRecognitionLabels.php b/src/File/AppData/AwsRecognitionLabels.php index 0c2e2f2..a7e6d31 100644 --- a/src/File/AppData/AwsRecognitionLabels.php +++ b/src/File/AppData/AwsRecognitionLabels.php @@ -6,11 +6,8 @@ use Uploadcare\Interfaces\File\AppData\AwsRecognitionLabelsInterface; use Uploadcare\Interfaces\SerializableInterface; -class AwsRecognitionLabels implements AwsRecognitionLabelsInterface, SerializableInterface +class AwsRecognitionLabels extends AbstractAwsLabels implements AwsRecognitionLabelsInterface, SerializableInterface { - private ?string $version = null; - private ?\DateTimeInterface $datetimeCreated = null; - private ?\DateTimeInterface $datetimeUpdated = null; private ?AwsRecognitionData $awsRecognitionData = null; public static function rules(): array @@ -23,42 +20,6 @@ public static function rules(): array ]; } - public function getVersion(): ?string - { - return $this->version; - } - - public function setVersion(?string $version): self - { - $this->version = $version; - - return $this; - } - - public function getDatetimeCreated(): ?\DateTimeInterface - { - return $this->datetimeCreated; - } - - public function setDatetimeCreated(?\DateTimeInterface $datetimeCreated): self - { - $this->datetimeCreated = $datetimeCreated; - - return $this; - } - - public function getDatetimeUpdated(): ?\DateTimeInterface - { - return $this->datetimeUpdated; - } - - public function setDatetimeUpdated(?\DateTimeInterface $datetimeUpdated): self - { - $this->datetimeUpdated = $datetimeUpdated; - - return $this; - } - public function getData(): ?AwsRecognitionDataInterface { return $this->awsRecognitionData; diff --git a/src/File/AppData/AwsRecognitionModerationData.php b/src/File/AppData/AwsRecognitionModerationData.php new file mode 100644 index 0000000..6ad7df6 --- /dev/null +++ b/src/File/AppData/AwsRecognitionModerationData.php @@ -0,0 +1,53 @@ + 'string', + 'moderationLabels' => [AwsModerationLabel::class], + ]; + } + + public function getLabelModelVersion(): ?string + { + return $this->labelModelVersion; + } + + public function setModerationModelVersion(?string $labelModelVersion): self + { + $this->labelModelVersion = $labelModelVersion; + + return $this; + } + + /** + * @return AwsModerationLabel[] + */ + public function getLabels(): iterable + { + return $this->moderationLabels; + } + + public function addModerationLabel(AwsModerationLabel $label): self + { + if (!\in_array($label, $this->moderationLabels, true)) { + $this->moderationLabels[] = $label; + } + + return $this; + } +} diff --git a/src/File/AppData/AwsRecognitionModerationLabels.php b/src/File/AppData/AwsRecognitionModerationLabels.php new file mode 100644 index 0000000..abf2f36 --- /dev/null +++ b/src/File/AppData/AwsRecognitionModerationLabels.php @@ -0,0 +1,34 @@ + 'string', + 'datetimeCreated' => \DateTime::class, + 'datetimeUpdated' => \DateTime::class, + 'data' => AwsRecognitionModerationData::class, + ]; + } + + public function getData(): ?AwsRecognitionDataInterface + { + return $this->awsRecognitionData; + } + + public function setData(?AwsRecognitionModerationData $data): self + { + $this->awsRecognitionData = $data; + + return $this; + } +} diff --git a/src/Group.php b/src/Group.php index ce47af3..91a23c3 100644 --- a/src/Group.php +++ b/src/Group.php @@ -39,6 +39,7 @@ public function getDatetimeCreated(): ?\DateTimeInterface public function getDatetimeStored(): ?\DateTimeInterface { + /** @psalm-suppress DeprecatedMethod */ return $this->inner->getDatetimeStored(); } diff --git a/src/Interfaces/Api/AddonsApiInterface.php b/src/Interfaces/Api/AddonsApiInterface.php index 7520a73..942d6db 100644 --- a/src/Interfaces/Api/AddonsApiInterface.php +++ b/src/Interfaces/Api/AddonsApiInterface.php @@ -8,6 +8,30 @@ interface AddonsApiInterface { + /** + * Execute AWS Rekognition Moderation Add-On for a given target to detect moderation labels in an image. + * Note: Detected moderation labels are stored in the file's appdata. + * + * @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Add-Ons/operation/awsRekognitionDetectModerationLabelsExecute + * @see https://docs.aws.amazon.com/rekognition/latest/dg/moderation.html + * + * @param FileInfoInterface|string $id + * + * @return string Request ID + * + * @throws HttpException|\RuntimeException + */ + public function requestAwsRecognitionModeration($id): string; + + /** + * Check the status of an Add-On execution request that had been started using the Execute Add-On operation. + * + * @param string $id Request ID + * + * @return string Status of AWS recognition. Could be "in_progress", "error", "done", "unknown" + */ + public function checkAwsRecognitionModeration(string $id): string; + /** * Execute AWS Rekognition Add-On for a given target to detect labels in an image. * Note: Detected labels are stored in the file's appdata. diff --git a/src/Interfaces/Api/WebhookApiInterface.php b/src/Interfaces/Api/WebhookApiInterface.php index 6bfc464..fff055d 100644 --- a/src/Interfaces/Api/WebhookApiInterface.php +++ b/src/Interfaces/Api/WebhookApiInterface.php @@ -17,6 +17,17 @@ interface WebhookApiInterface */ public function listWebhooks(): CollectionInterface; + /** + * @param string $targetUrl Webhook endpoint + * @param bool $isActive Is webhook active + * @param string|null $signingSecret Secret for sign a webhook endpoint call + * @param string $event The event can be any of `file.uploaded`, `file.info_updated`, `file.deleted`, `file.stored`, `file.infected` + * + * @return WebhookInterface Result of creation + * + * @see https://uploadcare.com/api-refs/rest-api/v0.7.0/#tag/Webhook + * @see https://uploadcare.com/docs/webhooks/ + */ public function createWebhook(string $targetUrl, bool $isActive = true, string $signingSecret = null, string $event = 'file.uploaded'): WebhookInterface; /** diff --git a/src/Interfaces/Conversion/ConversionRequestInterface.php b/src/Interfaces/Conversion/ConversionRequestInterface.php index 83d1a4e..0144903 100644 --- a/src/Interfaces/Conversion/ConversionRequestInterface.php +++ b/src/Interfaces/Conversion/ConversionRequestInterface.php @@ -12,4 +12,6 @@ public function getTargetFormat(): string; public function throwError(): bool; public function store(): bool; + + public function isSaveInGroup(): bool; } diff --git a/src/Interfaces/File/AppData/AwsRecognitionData/AwsModerationLabelInterface.php b/src/Interfaces/File/AppData/AwsRecognitionData/AwsModerationLabelInterface.php new file mode 100644 index 0000000..c9fe521 --- /dev/null +++ b/src/Interfaces/File/AppData/AwsRecognitionData/AwsModerationLabelInterface.php @@ -0,0 +1,12 @@ + + * @return iterable */ public function getLabels(): iterable; } diff --git a/src/Interfaces/File/AppDataInterface.php b/src/Interfaces/File/AppDataInterface.php index 0f783c5..59964e5 100644 --- a/src/Interfaces/File/AppDataInterface.php +++ b/src/Interfaces/File/AppDataInterface.php @@ -2,14 +2,13 @@ namespace Uploadcare\Interfaces\File; -use Uploadcare\Interfaces\File\AppData\ClamAvVirusScanInterface; -use Uploadcare\Interfaces\File\AppData\RemoveBgInterface; - interface AppDataInterface { + public function getAwsRekognitionDetectModerationLabels(): ?AppData\AwsRecognitionLabelsInterface; + public function getAwsRekognitionDetectLabels(): ?AppData\AwsRecognitionLabelsInterface; - public function getClamAvVirusScan(): ?ClamAvVirusScanInterface; + public function getClamAvVirusScan(): ?AppData\ClamAvVirusScanInterface; - public function getRemoveBg(): ?RemoveBgInterface; + public function getRemoveBg(): ?AppData\RemoveBgInterface; } diff --git a/src/Interfaces/GroupInterface.php b/src/Interfaces/GroupInterface.php index 51d58a3..23ecd48 100644 --- a/src/Interfaces/GroupInterface.php +++ b/src/Interfaces/GroupInterface.php @@ -21,6 +21,7 @@ public function getDatetimeCreated(): ?\DateTimeInterface; /** * Date and time when files in a group were stored. + * @deprecated */ public function getDatetimeStored(): ?\DateTimeInterface; diff --git a/src/Serializer/WordsConverter.php b/src/Serializer/WordsConverter.php index eaaad24..92de6a2 100644 --- a/src/Serializer/WordsConverter.php +++ b/src/Serializer/WordsConverter.php @@ -16,6 +16,7 @@ public static function conversions(): array 'files' => 'file', 'problems' => 'problem', 'labels' => 'label', + 'moderationLabels' => 'moderationLabel', 'parents' => 'parent', 'instances' => 'instance', ]; diff --git a/tests/Api/AddonsApiTest.php b/tests/Api/AddonsApiTest.php index 382b736..09fdded 100644 --- a/tests/Api/AddonsApiTest.php +++ b/tests/Api/AddonsApiTest.php @@ -64,4 +64,20 @@ public function testRemoveBackgroundMethods(): void self::assertSame($requestId, $api->requestRemoveBackground(\uuid_create(), $rr)); self::assertSame('done', $api->checkRemoveBackground($requestId)); } + + public function testRecognitionModerationMethods(): void + { + $id = \uuid_create(); + + $api = $this->fakeApi([ + new Response(200, [], \json_encode(['request_id' => $id])), + new Response(200, [], \json_encode(['status' => 'done'])), + ]); + + $result = $api->requestAwsRecognitionModeration(\uuid_create()); + self::assertSame($result, $id); + + $status = $api->checkAwsRecognitionModeration($id); + self::assertSame('done', $status); + } } diff --git a/tests/AppData/AwsDeserializationTest.php b/tests/AppData/AwsDeserializationTest.php index 7979bb1..3801a45 100644 --- a/tests/AppData/AwsDeserializationTest.php +++ b/tests/AppData/AwsDeserializationTest.php @@ -5,8 +5,11 @@ use PHPUnit\Framework\TestCase; use Uploadcare\File\AppData\AwsInstance; use Uploadcare\File\AppData\AwsLabel; +use Uploadcare\File\AppData\AwsModerationLabel; use Uploadcare\File\AppData\AwsRecognitionData; use Uploadcare\File\AppData\AwsRecognitionLabels; +use Uploadcare\File\AppData\AwsRecognitionModerationData; +use Uploadcare\File\AppData\AwsRecognitionModerationLabels; use Uploadcare\File\AppData\BoundingBox; use Uploadcare\File\AppData\LabelParent; use Uploadcare\Interfaces\Serializer\SerializerInterface; @@ -16,6 +19,7 @@ class AwsDeserializationTest extends TestCase { private string $awsLabels; + private string $awsModerationLabels; protected function setUp(): void { @@ -24,8 +28,11 @@ protected function setUp(): void $fileInfoArray = \json_decode($fileInfo, true, 512, JSON_THROW_ON_ERROR); $labels = $fileInfoArray['appdata']['aws_rekognition_detect_labels'] ?? null; self::assertIsArray($labels); - $this->awsLabels = \json_encode($labels, JSON_THROW_ON_ERROR); + + $moderationLabels = $fileInfoArray['appdata']['aws_rekognition_detect_moderation_labels'] ?? null; + self::assertIsArray($moderationLabels); + $this->awsModerationLabels = \json_encode($moderationLabels, JSON_THROW_ON_ERROR); } protected function getSerializer(): SerializerInterface @@ -33,7 +40,7 @@ protected function getSerializer(): SerializerInterface return new Serializer(new SnackCaseConverter()); } - public function testDeserialization(): void + public function testLabelsDeserialization(): void { $result = $this->getSerializer()->deserialize($this->awsLabels, AwsRecognitionLabels::class); self::assertInstanceOf(AwsRecognitionLabels::class, $result); @@ -69,4 +76,24 @@ public function testDeserialization(): void self::assertNotEmpty($instance->getConfidence()); self::assertInstanceOf(BoundingBox::class, $instance->getBoundingBox()); } + + public function testModerationLabelsDeserialization(): void + { + $result = $this->getSerializer()->deserialize($this->awsModerationLabels, AwsRecognitionModerationLabels::class); + self::assertInstanceOf(AwsRecognitionModerationLabels::class, $result); + self::assertInstanceOf(\DateTimeInterface::class, $result->getDatetimeCreated()); + self::assertInstanceOf(\DateTimeInterface::class, $result->getDatetimeUpdated()); + + $data = $result->getData(); + self::assertInstanceOf(AwsRecognitionModerationData::class, $data); + self::assertSame('6.0', $data->getLabelModelVersion()); + $labels = $data->getLabels(); + self::assertNotEmpty($labels); + + $label = \reset($labels); + self::assertInstanceOf(AwsModerationLabel::class, $label); + self::assertIsFloat($label->getConfidence()); + self::assertEquals('Weapons', $label->getName()); + self::assertEquals('Violence', $label->getParentName()); + } } diff --git a/tests/Metadata/MetadataRealApiTest.php b/tests/Metadata/MetadataRealApiTest.php index abbf9bd..141b224 100644 --- a/tests/Metadata/MetadataRealApiTest.php +++ b/tests/Metadata/MetadataRealApiTest.php @@ -33,7 +33,9 @@ public function testFileMetadataLoad(): void $value = \date_create()->format(\DateTimeInterface::ATOM); $api->metadata()->setKey($file, $key, $value); + $dateOne = \date_create($value)->format('Y-m-d'); + $dateTwo = \date_create($file->getMetadata()->offsetGet($key))->format('Y-m-d'); - self::assertSame($value, $file->getMetadata()->offsetGet($key)); + self::assertSame($dateOne, $dateTwo); } } diff --git a/tests/Metadata/MetadataTest.php b/tests/Metadata/MetadataTest.php index 55131f8..4b36923 100644 --- a/tests/Metadata/MetadataTest.php +++ b/tests/Metadata/MetadataTest.php @@ -2,12 +2,18 @@ namespace Tests\Metadata; +use GuzzleHttp\ClientInterface; +use GuzzleHttp\Exception\ConnectException; +use GuzzleHttp\Psr7\Request; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\ResponseInterface; use Symfony\Component\String\ByteString; use Uploadcare\Apis\MetadataApi; use Uploadcare\Configuration; -use Uploadcare\Exception\MetadataException; +use Uploadcare\Exception\{HttpException, MetadataException}; use Uploadcare\File\Metadata; +use Uploadcare\Security\Signature; +use Uploadcare\Serializer\SerializerFactory; class MetadataTest extends TestCase { @@ -55,4 +61,44 @@ public function testSetKeyMethodWithWrongValue(): void $api->setKey(\uuid_create(), $key, $value); } + + public function testRemoveReyWithTheWrongKey(): void + { + $key = ByteString::fromRandom(128)->toString(); + + $api = new MetadataApi(Configuration::create('demo', 'demo')); + $this->expectException(MetadataException::class); + $this->expectExceptionMessageMatches('/Key should be string up to 64 characters length/'); + + $api->removeKey(\uuid_create(), $key); + } + + public function testRemoveKeyWithAnErrorInTheResponse(): void + { + $client = $this->createMock(ClientInterface::class); + $client->expects(self::atLeastOnce())->method('request')->willThrowException(new ConnectException('Error string', new Request('DELETE', 'https://example.com'))); + $configuration = new Configuration('demo', new Signature('demo'), $client, SerializerFactory::create()); + + $key = 'validString'; + $api = new MetadataApi($configuration); + $this->expectException(HttpException::class); + + $api->removeKey(\uuid_create(), $key); + } + + public function testRemoveKeyWithTheWrongResponseStatus(): void + { + $response = $this->createMock(ResponseInterface::class); + $response->expects(self::atLeastOnce())->method('getStatusCode')->willReturn(401); + $client = $this->createMock(ClientInterface::class); + $client->expects(self::atLeastOnce())->method('request')->willReturn($response); + $configuration = new Configuration('demo', new Signature('demo'), $client, SerializerFactory::create()); + + $key = 'validString'; + $api = new MetadataApi($configuration); + $this->expectException(HttpException::class); + $this->expectExceptionMessageMatches('/Wrong response. Call to support/'); + + $api->removeKey(\uuid_create(), $key); + } } diff --git a/tests/_data/file-info.json b/tests/_data/file-info.json index 030ff07..3bb706e 100644 --- a/tests/_data/file-info.json +++ b/tests/_data/file-info.json @@ -39,6 +39,21 @@ "foo": "2022-09-18T08:13:31+00:00" }, "appdata": { + "aws_rekognition_detect_moderation_labels": { + "data": { + "ModerationModelVersion": "6.0", + "ModerationLabels": [ + { + "Confidence": 93.41645812988281, + "Name": "Weapons", + "ParentName": "Violence" + } + ] + }, + "version": "2016-06-27", + "datetime_created": "2023-02-21T11:25:31.259763Z", + "datetime_updated": "2023-02-21T11:27:33.359763Z" + }, "aws_rekognition_detect_labels": { "data": { "Labels": [