From be17d9fa654a10c9ac109bc78a2f0c4956e24a3b Mon Sep 17 00:00:00 2001 From: mehmet-yoti Date: Thu, 24 Sep 2026 06:22:36 +0100 Subject: [PATCH] SDK-2529 PHP - Create helper methods for the IDV SDK --- .../Session/Retrieve/GetSessionResult.php | 21 ++++ .../Session/Retrieve/ResourceContainer.php | 39 ++++++ .../Session/Retrieve/GetSessionResultTest.php | 72 ++++++++++++ .../Retrieve/ResourceContainerTest.php | 111 ++++++++++++++++++ 4 files changed, 243 insertions(+) diff --git a/src/DocScan/Session/Retrieve/GetSessionResult.php b/src/DocScan/Session/Retrieve/GetSessionResult.php index 16e3f788..44850b4b 100644 --- a/src/DocScan/Session/Retrieve/GetSessionResult.php +++ b/src/DocScan/Session/Retrieve/GetSessionResult.php @@ -359,4 +359,25 @@ public function getImportToken(): ?ImportTokenResponse { return $this->importToken; } + + /** + * Returns the resources used by the check matching the given check ID. + * + * @param string $checkId + * @return ResourceContainer + * + * @throws \InvalidArgumentException if no check exists with the given ID + */ + public function getResourcesForCheck(string $checkId): ResourceContainer + { + foreach ($this->checks as $check) { + if ($check->getId() === $checkId) { + return isset($this->resources) + ? $this->resources->filterForCheck($check) + : new ResourceContainer([]); + } + } + + throw new \InvalidArgumentException('Check not found'); + } } diff --git a/src/DocScan/Session/Retrieve/ResourceContainer.php b/src/DocScan/Session/Retrieve/ResourceContainer.php index dd0d07c3..c0bfca49 100644 --- a/src/DocScan/Session/Retrieve/ResourceContainer.php +++ b/src/DocScan/Session/Retrieve/ResourceContainer.php @@ -236,4 +236,43 @@ function ($resourceResponse) use ($class): bool { return array_values($filtered); } + + /** + * Returns a new ResourceContainer containing only the resources referenced + * by the given check's "resources used" list. + * + * @param CheckResponse $checkResponse + * @return ResourceContainer + */ + public function filterForCheck(CheckResponse $checkResponse): ResourceContainer + { + $resourceIds = $checkResponse->getResourcesUsed(); + + $filtered = new ResourceContainer([]); + $filtered->idDocuments = $this->filterResourcesByIds($this->idDocuments, $resourceIds); + $filtered->supplementaryDocuments = $this->filterResourcesByIds($this->supplementaryDocuments, $resourceIds); + $filtered->livenessCapture = $this->filterResourcesByIds($this->livenessCapture, $resourceIds); + $filtered->faceCapture = $this->filterResourcesByIds($this->faceCapture, $resourceIds); + $filtered->shareCodes = $this->filterResourcesByIds($this->shareCodes, $resourceIds); + $filtered->applicantProfiles = $this->filterResourcesByIds($this->applicantProfiles, $resourceIds); + + return $filtered; + } + + /** + * @param ResourceResponse[] $resources + * @param string[] $resourceIds + * @return mixed[] + */ + private function filterResourcesByIds(array $resources, array $resourceIds): array + { + $filtered = array_filter( + $resources, + function (ResourceResponse $resource) use ($resourceIds): bool { + return in_array($resource->getId(), $resourceIds, true); + } + ); + + return array_values($filtered); + } } diff --git a/tests/DocScan/Session/Retrieve/GetSessionResultTest.php b/tests/DocScan/Session/Retrieve/GetSessionResultTest.php index ee30dddb..3b4bf399 100644 --- a/tests/DocScan/Session/Retrieve/GetSessionResultTest.php +++ b/tests/DocScan/Session/Retrieve/GetSessionResultTest.php @@ -13,6 +13,7 @@ use Yoti\DocScan\Session\Retrieve\IdentityProfileResponse; use Yoti\DocScan\Session\Retrieve\ImportTokenResponse; use Yoti\DocScan\Session\Retrieve\MediaResponse; +use Yoti\DocScan\Session\Retrieve\ResourceContainer; use Yoti\DocScan\Session\Retrieve\ThirdPartyIdentityFraudOneCheckResponse; use Yoti\Test\TestCase; use Yoti\Util\DateTime; @@ -354,4 +355,75 @@ public function shouldReturnNullWhenAdvancedIdentityProfileNotPresent() $this->assertNull($result->getAdvancedIdentityProfile()); $this->assertNull($result->getAdvancedIdentityProfilePreview()); } + + /** + * @test + * @covers ::getResourcesForCheck + */ + public function shouldReturnResourcesForCheck() + { + $input = [ + 'checks' => [ + [ + 'id' => 'some-check-id', + 'type' => self::ID_DOCUMENT_AUTHENTICITY, + 'resources_used' => ['some-id-document-id'], + ], + ], + 'resources' => [ + 'id_documents' => [ + ['id' => 'some-id-document-id'], + ['id' => 'some-other-id-document-id'], + ], + ], + ]; + + $result = new GetSessionResult($input); + + $resourcesForCheck = $result->getResourcesForCheck('some-check-id'); + + $this->assertInstanceOf(ResourceContainer::class, $resourcesForCheck); + $this->assertCount(1, $resourcesForCheck->getIdDocuments()); + $this->assertEquals('some-id-document-id', $resourcesForCheck->getIdDocuments()[0]->getId()); + } + + /** + * @test + * @covers ::getResourcesForCheck + */ + public function shouldReturnEmptyResourceContainerWhenSessionHasNoResources() + { + $input = [ + 'checks' => [ + ['id' => 'some-check-id', 'type' => self::ID_DOCUMENT_AUTHENTICITY], + ], + ]; + + $result = new GetSessionResult($input); + + $resourcesForCheck = $result->getResourcesForCheck('some-check-id'); + + $this->assertInstanceOf(ResourceContainer::class, $resourcesForCheck); + $this->assertCount(0, $resourcesForCheck->getIdDocuments()); + } + + /** + * @test + * @covers ::getResourcesForCheck + */ + public function shouldThrowExceptionWhenCheckIdNotFound() + { + $input = [ + 'checks' => [ + ['id' => 'some-check-id', 'type' => self::ID_DOCUMENT_AUTHENTICITY], + ], + ]; + + $result = new GetSessionResult($input); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Check not found'); + + $result->getResourcesForCheck('some-unknown-check-id'); + } } diff --git a/tests/DocScan/Session/Retrieve/ResourceContainerTest.php b/tests/DocScan/Session/Retrieve/ResourceContainerTest.php index f73beb81..eadae98e 100644 --- a/tests/DocScan/Session/Retrieve/ResourceContainerTest.php +++ b/tests/DocScan/Session/Retrieve/ResourceContainerTest.php @@ -5,6 +5,7 @@ namespace Yoti\Test\DocScan\Session\Retrieve; use Yoti\DocScan\Session\Retrieve\ApplicantProfileResourceResponse; +use Yoti\DocScan\Session\Retrieve\CheckResponse; use Yoti\DocScan\Session\Retrieve\ResourceContainer; use Yoti\DocScan\Session\Retrieve\ShareCodeResourceResponse; use Yoti\DocScan\Session\Retrieve\StaticLivenessResourceResponse; @@ -219,4 +220,114 @@ public function shouldParseApplicantProfiles(): void $result->getApplicantProfiles()[0]->getId() ); } + + /** + * @test + * @covers ::filterForCheck + * @covers ::filterResourcesByIds + */ + public function shouldFilterForCheckAndReturnFilteredCollections(): void + { + $input = [ + 'id_documents' => [ + ['id' => 'id-document-1'], + ['id' => 'id-document-2'], + ], + 'supplementary_documents' => [ + ['id' => 'supplementary-document-1'], + ['id' => 'supplementary-document-2'], + ], + 'liveness_capture' => [ + ['id' => 'liveness-1', 'liveness_type' => 'ZOOM'], + ['id' => 'liveness-2', 'liveness_type' => 'ZOOM'], + ], + 'face_capture' => [ + ['id' => 'face-capture-1'], + ['id' => 'face-capture-2'], + ], + 'share_codes' => [ + ['id' => 'share-code-1'], + ['id' => 'share-code-2'], + ], + 'applicant_profiles' => [ + ['id' => 'applicant-profile-1'], + ['id' => 'applicant-profile-2'], + ], + ]; + + $checkResponse = new CheckResponse([ + 'resources_used' => [ + 'id-document-1', + 'supplementary-document-1', + 'liveness-1', + 'face-capture-1', + 'share-code-1', + 'applicant-profile-1', + ], + ]); + + $result = (new ResourceContainer($input))->filterForCheck($checkResponse); + + $this->assertCount(1, $result->getIdDocuments()); + $this->assertEquals('id-document-1', $result->getIdDocuments()[0]->getId()); + + $this->assertCount(1, $result->getSupplementaryDocuments()); + $this->assertEquals('supplementary-document-1', $result->getSupplementaryDocuments()[0]->getId()); + + $this->assertCount(1, $result->getLivenessCapture()); + $this->assertEquals('liveness-1', $result->getLivenessCapture()[0]->getId()); + + $this->assertCount(1, $result->getFaceCapture()); + $this->assertEquals('face-capture-1', $result->getFaceCapture()[0]->getId()); + + $this->assertCount(1, $result->getShareCodes()); + $this->assertEquals('share-code-1', $result->getShareCodes()[0]->getId()); + + $this->assertCount(1, $result->getApplicantProfiles()); + $this->assertEquals('applicant-profile-1', $result->getApplicantProfiles()[0]->getId()); + } + + /** + * @test + * @covers ::filterForCheck + * @covers ::filterResourcesByIds + */ + public function shouldFilterForCheckAndReturnEmptyCollectionsWhenNoMatches(): void + { + $input = [ + 'id_documents' => [ + ['id' => 'id-document-1'], + ], + ]; + + $checkResponse = new CheckResponse(['resources_used' => ['someUnrelatedResourceId']]); + + $result = (new ResourceContainer($input))->filterForCheck($checkResponse); + + $this->assertCount(0, $result->getIdDocuments()); + $this->assertCount(0, $result->getSupplementaryDocuments()); + $this->assertCount(0, $result->getLivenessCapture()); + $this->assertCount(0, $result->getFaceCapture()); + $this->assertCount(0, $result->getShareCodes()); + $this->assertCount(0, $result->getApplicantProfiles()); + } + + /** + * @test + * @covers ::filterForCheck + * @covers ::filterResourcesByIds + */ + public function shouldFilterForCheckAndReturnEmptyCollectionsWhenContainerHasNoResources(): void + { + $checkResponse = new CheckResponse(['resources_used' => ['someResourceId']]); + + $result = (new ResourceContainer([]))->filterForCheck($checkResponse); + + $this->assertCount(0, $result->getIdDocuments()); + $this->assertCount(0, $result->getSupplementaryDocuments()); + $this->assertCount(0, $result->getLivenessCapture()); + $this->assertCount(0, $result->getFaceCapture()); + $this->assertCount(0, $result->getShareCodes()); + $this->assertCount(0, $result->getApplicantProfiles()); + } }