diff --git a/README.md b/README.md
index a68b056b..2dcfeaa4 100755
--- a/README.md
+++ b/README.md
@@ -30,6 +30,9 @@ Please feel free to reach out
* PHP ^8.1
* CURL PHP extension (must support TLSv1.2)
+> **Breaking change:** this SDK release supports PHP 8.1 and above only.
+> Support for PHP 7.4 and PHP 8.0 has been removed.
+> If you are still running on PHP 7.4/8.0, please remain on an earlier SDK version until you can upgrade your runtime.
### Recommended (optional)
- [Protobuf C extension](https://github.com/protocolbuffers/protobuf/tree/master/php) (PHP package will be used by default)
@@ -42,13 +45,13 @@ Add the Yoti SDK dependency:
```json
"require": {
- "yoti/yoti-php-sdk" : "^4.5.0"
+ "yoti/yoti-php-sdk" : "^4.5.1"
}
```
Or run this Composer command
```console
-$ composer require yoti/yoti-php-sdk "^4.5.0"
+$ composer require yoti/yoti-php-sdk "^4.5.1"
```
## Setup
diff --git a/composer.json b/composer.json
index 91b4d313..d913b799 100755
--- a/composer.json
+++ b/composer.json
@@ -1,7 +1,7 @@
{
"name": "yoti/yoti-php-sdk",
"description": "Yoti SDK for quickly integrating your PHP backend with Yoti",
- "version": "4.5.0",
+ "version": "4.5.1",
"keywords": [
"yoti",
"sdk"
diff --git a/examples/doc-scan/app/Http/Controllers/HomeController.php b/examples/doc-scan/app/Http/Controllers/HomeController.php
index 77d84441..53aec60f 100644
--- a/examples/doc-scan/app/Http/Controllers/HomeController.php
+++ b/examples/doc-scan/app/Http/Controllers/HomeController.php
@@ -152,6 +152,19 @@ public function show(Request $request, DocScanClient $client)
->withPrivacyPolicyUrl(config('app.url') . '/privacy-policy')
->withBiometricConsentFlow('EARLY')
//->withBrandId('brand_id')
+ // Suppress specific screens to shorten the flow.
+ // Available screen identifiers:
+ // 'IDENTITY_DOCUMENT_EDUCATION'
+ // 'IDENTITY_DOCUMENT_REQUIREMENTS'
+ // 'SUPPLEMENTARY_DOCUMENT_REQUIREMENTS'
+ // 'ZOOM_LIVENESS_EDUCATION'
+ // 'STATIC_LIVENESS_EDUCATION'
+ // 'FACE_CAPTURE_EDUCATION'
+ // 'FLOW_COMPLETION'
+ // ->withSuppressedScreens(['IDENTITY_DOCUMENT_EDUCATION', 'IDENTITY_DOCUMENT_REQUIREMENTS'])
+ // Or add screens individually:
+ // ->withSuppressedScreen('IDENTITY_DOCUMENT_EDUCATION')
+ // ->withSuppressedScreen('IDENTITY_DOCUMENT_REQUIREMENTS')
->build()
)
->withRequiredDocument(
diff --git a/examples/doc-scan/resources/views/partial/check.blade.php b/examples/doc-scan/resources/views/partial/check.blade.php
index 651a6b22..062ddaeb 100644
--- a/examples/doc-scan/resources/views/partial/check.blade.php
+++ b/examples/doc-scan/resources/views/partial/check.blade.php
@@ -67,6 +67,12 @@
Result |
{{ $breakdown->getResult() }} |
+ @if ($breakdown->getProcess())
+
+ | Process |
+ {{ $breakdown->getProcess() }} |
+
+ @endif
@if (count($breakdown->getDetails()) > 0)
| Details |
diff --git a/examples/doc-scan/resources/views/success.blade.php b/examples/doc-scan/resources/views/success.blade.php
index 63b0b486..612311ca 100644
--- a/examples/doc-scan/resources/views/success.blade.php
+++ b/examples/doc-scan/resources/views/success.blade.php
@@ -562,6 +562,23 @@ class="badge badge-primary">{{ $document->getIssuingCountry() }}
@endif
+ @if (count($page->getExtractionImageIds()) > 0)
+
+
+
+
Extraction Image IDs
+
+
+
+
+ @endif
+
@endforeach
@@ -743,6 +760,23 @@ class="badge badge-primary">{{ $document->getIssuingCountry() }}
@endif
+ @if (count($page->getExtractionImageIds()) > 0)
+
+
+
+
Extraction Image IDs
+
+
+
+
+ @endif
+
@endforeach
diff --git a/src/Constants.php b/src/Constants.php
index 921b1fbe..51053dfe 100644
--- a/src/Constants.php
+++ b/src/Constants.php
@@ -37,7 +37,7 @@ class Constants
public const SDK_IDENTIFIER = 'PHP';
/** Default SDK version */
- public const SDK_VERSION = '4.5.0';
+ public const SDK_VERSION = '4.5.1';
/** Base url for connect page (user will be redirected to this page eg. baseurl/app-id) */
public const CONNECT_BASE_URL = 'https://www.yoti.com/connect';
diff --git a/src/DocScan/Session/Create/ApplicantProfile.php b/src/DocScan/Session/Create/ApplicantProfile.php
new file mode 100644
index 00000000..0eb26dc0
--- /dev/null
+++ b/src/DocScan/Session/Create/ApplicantProfile.php
@@ -0,0 +1,95 @@
+fullName = $fullName;
+ $this->dateOfBirth = $dateOfBirth;
+ $this->namePrefix = $namePrefix;
+ $this->structuredPostalAddress = $structuredPostalAddress;
+ }
+
+ /**
+ * @return stdClass
+ */
+ public function jsonSerialize(): stdClass
+ {
+ return (object) Json::withoutNullValues([
+ 'full_name' => $this->fullName,
+ 'date_of_birth' => $this->dateOfBirth,
+ 'name_prefix' => $this->namePrefix,
+ 'structured_postal_address' => $this->structuredPostalAddress,
+ ]);
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getFullName(): ?string
+ {
+ return $this->fullName;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getDateOfBirth(): ?string
+ {
+ return $this->dateOfBirth;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getNamePrefix(): ?string
+ {
+ return $this->namePrefix;
+ }
+
+ /**
+ * @return StructuredPostalAddress|null
+ */
+ public function getStructuredPostalAddress(): ?StructuredPostalAddress
+ {
+ return $this->structuredPostalAddress;
+ }
+}
diff --git a/src/DocScan/Session/Create/ApplicantProfileBuilder.php b/src/DocScan/Session/Create/ApplicantProfileBuilder.php
new file mode 100644
index 00000000..e0c85d3d
--- /dev/null
+++ b/src/DocScan/Session/Create/ApplicantProfileBuilder.php
@@ -0,0 +1,81 @@
+fullName = $fullName;
+ return $this;
+ }
+
+ /**
+ * @param string $dateOfBirth
+ * @return $this
+ */
+ public function withDateOfBirth(string $dateOfBirth): self
+ {
+ $this->dateOfBirth = $dateOfBirth;
+ return $this;
+ }
+
+ /**
+ * @param string $namePrefix
+ * @return $this
+ */
+ public function withNamePrefix(string $namePrefix): self
+ {
+ $this->namePrefix = $namePrefix;
+ return $this;
+ }
+
+ /**
+ * @param StructuredPostalAddress $structuredPostalAddress
+ * @return $this
+ */
+ public function withStructuredPostalAddress(StructuredPostalAddress $structuredPostalAddress): self
+ {
+ $this->structuredPostalAddress = $structuredPostalAddress;
+ return $this;
+ }
+
+ /**
+ * @return ApplicantProfile
+ */
+ public function build(): ApplicantProfile
+ {
+ return new ApplicantProfile(
+ $this->fullName,
+ $this->dateOfBirth,
+ $this->namePrefix,
+ $this->structuredPostalAddress
+ );
+ }
+}
diff --git a/src/DocScan/Session/Create/ResourceCreationContainer.php b/src/DocScan/Session/Create/ResourceCreationContainer.php
new file mode 100644
index 00000000..ebbbd776
--- /dev/null
+++ b/src/DocScan/Session/Create/ResourceCreationContainer.php
@@ -0,0 +1,43 @@
+applicantProfile = $applicantProfile;
+ }
+
+ /**
+ * @return stdClass
+ */
+ public function jsonSerialize(): stdClass
+ {
+ return (object) Json::withoutNullValues([
+ 'applicant_profile' => $this->applicantProfile,
+ ]);
+ }
+
+ /**
+ * @return ApplicantProfile|null
+ */
+ public function getApplicantProfile(): ?ApplicantProfile
+ {
+ return $this->applicantProfile;
+ }
+}
diff --git a/src/DocScan/Session/Create/ResourceCreationContainerBuilder.php b/src/DocScan/Session/Create/ResourceCreationContainerBuilder.php
new file mode 100644
index 00000000..9ea9e394
--- /dev/null
+++ b/src/DocScan/Session/Create/ResourceCreationContainerBuilder.php
@@ -0,0 +1,33 @@
+applicantProfile = $applicantProfile;
+ return $this;
+ }
+
+ /**
+ * @return ResourceCreationContainer
+ */
+ public function build(): ResourceCreationContainer
+ {
+ return new ResourceCreationContainer(
+ $this->applicantProfile
+ );
+ }
+}
diff --git a/src/DocScan/Session/Create/SessionSpecification.php b/src/DocScan/Session/Create/SessionSpecification.php
index e080e5d0..060245d7 100644
--- a/src/DocScan/Session/Create/SessionSpecification.php
+++ b/src/DocScan/Session/Create/SessionSpecification.php
@@ -90,6 +90,11 @@ class SessionSpecification implements JsonSerializable
*/
private $importToken;
+ /**
+ * @var ResourceCreationContainer|null
+ */
+ private $resources;
+
/**
* @param int|null $clientSessionTokenTtl
* @param string|null $sessionDeadline
@@ -107,6 +112,7 @@ class SessionSpecification implements JsonSerializable
* @param object|null $advancedIdentityProfileRequirements
* @param bool|null $createIdentityProfilePreview
* @param ImportToken|null $importToken
+ * @param ResourceCreationContainer|null $resources
*/
public function __construct(
?int $clientSessionTokenTtl,
@@ -124,7 +130,8 @@ public function __construct(
?object $identityProfileRequirements = null,
?object $advancedIdentityProfileRequirements = null,
?bool $createIdentityProfilePreview = null,
- ?ImportToken $importToken = null
+ ?ImportToken $importToken = null,
+ ?ResourceCreationContainer $resources = null
) {
$this->clientSessionTokenTtl = $clientSessionTokenTtl;
$this->sessionDeadline = $sessionDeadline;
@@ -142,6 +149,7 @@ public function __construct(
$this->advancedIdentityProfileRequirements = $advancedIdentityProfileRequirements;
$this->createIdentityProfilePreview = $createIdentityProfilePreview;
$this->importToken = $importToken;
+ $this->resources = $resources;
}
/**
@@ -166,6 +174,7 @@ public function jsonSerialize(): stdClass
'advanced_identity_profile_requirements' => $this->getAdvancedIdentityProfileRequirements(),
'create_identity_profile_preview' => $this->getCreateIdentityProfilePreview(),
'import_token' => $this->getImportToken(),
+ 'resources' => $this->getResources(),
]);
}
@@ -295,4 +304,12 @@ public function getImportToken(): ?ImportToken
{
return $this->importToken;
}
+
+ /**
+ * @return ResourceCreationContainer|null
+ */
+ public function getResources(): ?ResourceCreationContainer
+ {
+ return $this->resources;
+ }
}
diff --git a/src/DocScan/Session/Create/SessionSpecificationBuilder.php b/src/DocScan/Session/Create/SessionSpecificationBuilder.php
index 5afc9c0c..2348a16e 100644
--- a/src/DocScan/Session/Create/SessionSpecificationBuilder.php
+++ b/src/DocScan/Session/Create/SessionSpecificationBuilder.php
@@ -88,6 +88,11 @@ class SessionSpecificationBuilder
*/
private $importToken;
+ /**
+ * @var ResourceCreationContainer|null
+ */
+ private $resources;
+
/**
* @var bool
*/
@@ -292,6 +297,19 @@ public function withImportToken($importToken): self
return $this;
}
+ /**
+ * Sets the resources for the session
+ *
+ * @param ResourceCreationContainer $resources
+ *
+ * @return $this
+ */
+ public function withResources(ResourceCreationContainer $resources): self
+ {
+ $this->resources = $resources;
+ return $this;
+ }
+
/**
* @return SessionSpecification
*/
@@ -314,6 +332,7 @@ public function build(): SessionSpecification
$this->advancedIdentityProfileRequirements,
$this->createIdentityProfilePreview,
$this->importToken,
+ $this->resources,
);
}
}
diff --git a/src/DocScan/Session/Create/StructuredPostalAddress.php b/src/DocScan/Session/Create/StructuredPostalAddress.php
new file mode 100644
index 00000000..bb915e4f
--- /dev/null
+++ b/src/DocScan/Session/Create/StructuredPostalAddress.php
@@ -0,0 +1,163 @@
+addressFormat = $addressFormat;
+ $this->buildingNumber = $buildingNumber;
+ $this->addressLine1 = $addressLine1;
+ $this->townCity = $townCity;
+ $this->postalCode = $postalCode;
+ $this->countryIso = $countryIso;
+ $this->country = $country;
+ $this->formattedAddress = $formattedAddress;
+ }
+
+ /**
+ * @return stdClass
+ */
+ public function jsonSerialize(): stdClass
+ {
+ return (object) Json::withoutNullValues([
+ 'address_format' => $this->addressFormat,
+ 'building_number' => $this->buildingNumber,
+ 'address_line1' => $this->addressLine1,
+ 'town_city' => $this->townCity,
+ 'postal_code' => $this->postalCode,
+ 'country_iso' => $this->countryIso,
+ 'country' => $this->country,
+ 'formatted_address' => $this->formattedAddress,
+ ]);
+ }
+
+ /**
+ * @return int|null
+ */
+ public function getAddressFormat(): ?int
+ {
+ return $this->addressFormat;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getBuildingNumber(): ?string
+ {
+ return $this->buildingNumber;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getAddressLine1(): ?string
+ {
+ return $this->addressLine1;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getTownCity(): ?string
+ {
+ return $this->townCity;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getPostalCode(): ?string
+ {
+ return $this->postalCode;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getCountryIso(): ?string
+ {
+ return $this->countryIso;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getCountry(): ?string
+ {
+ return $this->country;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getFormattedAddress(): ?string
+ {
+ return $this->formattedAddress;
+ }
+}
diff --git a/src/DocScan/Session/Create/StructuredPostalAddressBuilder.php b/src/DocScan/Session/Create/StructuredPostalAddressBuilder.php
new file mode 100644
index 00000000..3750c25f
--- /dev/null
+++ b/src/DocScan/Session/Create/StructuredPostalAddressBuilder.php
@@ -0,0 +1,145 @@
+addressFormat = $addressFormat;
+ return $this;
+ }
+
+ /**
+ * @param string $buildingNumber
+ * @return $this
+ */
+ public function withBuildingNumber(string $buildingNumber): self
+ {
+ $this->buildingNumber = $buildingNumber;
+ return $this;
+ }
+
+ /**
+ * @param string $addressLine1
+ * @return $this
+ */
+ public function withAddressLine1(string $addressLine1): self
+ {
+ $this->addressLine1 = $addressLine1;
+ return $this;
+ }
+
+ /**
+ * @param string $townCity
+ * @return $this
+ */
+ public function withTownCity(string $townCity): self
+ {
+ $this->townCity = $townCity;
+ return $this;
+ }
+
+ /**
+ * @param string $postalCode
+ * @return $this
+ */
+ public function withPostalCode(string $postalCode): self
+ {
+ $this->postalCode = $postalCode;
+ return $this;
+ }
+
+ /**
+ * @param string $countryIso
+ * @return $this
+ */
+ public function withCountryIso(string $countryIso): self
+ {
+ $this->countryIso = $countryIso;
+ return $this;
+ }
+
+ /**
+ * @param string $country
+ * @return $this
+ */
+ public function withCountry(string $country): self
+ {
+ $this->country = $country;
+ return $this;
+ }
+
+ /**
+ * @param string $formattedAddress
+ * @return $this
+ */
+ public function withFormattedAddress(string $formattedAddress): self
+ {
+ $this->formattedAddress = $formattedAddress;
+ return $this;
+ }
+
+ /**
+ * @return StructuredPostalAddress
+ */
+ public function build(): StructuredPostalAddress
+ {
+ return new StructuredPostalAddress(
+ $this->addressFormat,
+ $this->buildingNumber,
+ $this->addressLine1,
+ $this->townCity,
+ $this->postalCode,
+ $this->countryIso,
+ $this->country,
+ $this->formattedAddress
+ );
+ }
+}
diff --git a/src/DocScan/Session/Retrieve/ApplicantProfileResourceResponse.php b/src/DocScan/Session/Retrieve/ApplicantProfileResourceResponse.php
new file mode 100644
index 00000000..35dc108b
--- /dev/null
+++ b/src/DocScan/Session/Retrieve/ApplicantProfileResourceResponse.php
@@ -0,0 +1,70 @@
+ $applicantProfile
+ * @throws DateTimeException
+ */
+ public function __construct(array $applicantProfile)
+ {
+ parent::__construct($applicantProfile);
+
+ if (isset($applicantProfile['media'])) {
+ $this->media = new MediaResponse($applicantProfile['media']);
+ }
+
+ $this->createdAt = isset($applicantProfile['created_at'])
+ ? DateTime::stringToDateTime($applicantProfile['created_at']) : null;
+
+ $this->lastUpdated = isset($applicantProfile['last_updated'])
+ ? DateTime::stringToDateTime($applicantProfile['last_updated']) : null;
+ }
+
+ /**
+ * @return MediaResponse|null
+ */
+ public function getMedia(): ?MediaResponse
+ {
+ return $this->media;
+ }
+
+ /**
+ * @return \DateTime|null
+ */
+ public function getCreatedAt(): ?\DateTime
+ {
+ return $this->createdAt;
+ }
+
+ /**
+ * @return \DateTime|null
+ */
+ public function getLastUpdated(): ?\DateTime
+ {
+ return $this->lastUpdated;
+ }
+}
diff --git a/src/DocScan/Session/Retrieve/BreakdownResponse.php b/src/DocScan/Session/Retrieve/BreakdownResponse.php
index 8e9ba9c3..410e635c 100644
--- a/src/DocScan/Session/Retrieve/BreakdownResponse.php
+++ b/src/DocScan/Session/Retrieve/BreakdownResponse.php
@@ -16,6 +16,11 @@ class BreakdownResponse
*/
private $result;
+ /**
+ * @var string|null
+ */
+ private $process;
+
/**
* @var DetailsResponse[]
*/
@@ -29,6 +34,7 @@ public function __construct(array $breakdown)
{
$this->subCheck = $breakdown['sub_check'] ?? null;
$this->result = $breakdown['result'] ?? null;
+ $this->process = $breakdown['process'] ?? null;
if (isset($breakdown['details'])) {
foreach ($breakdown['details'] as $detail) {
@@ -53,6 +59,14 @@ public function getResult(): ?string
return $this->result;
}
+ /**
+ * @return string|null
+ */
+ public function getProcess(): ?string
+ {
+ return $this->process;
+ }
+
/**
* @return DetailsResponse[]
*/
diff --git a/src/DocScan/Session/Retrieve/PageResponse.php b/src/DocScan/Session/Retrieve/PageResponse.php
index 163b9ecf..62805cd0 100644
--- a/src/DocScan/Session/Retrieve/PageResponse.php
+++ b/src/DocScan/Session/Retrieve/PageResponse.php
@@ -21,6 +21,11 @@ class PageResponse
*/
private $frames = [];
+ /**
+ * @var string[]
+ */
+ private $extractionImageIds = [];
+
/**
* PageInfo constructor.
* @param array $page
@@ -38,6 +43,10 @@ public function __construct(array $page)
$this->frames[] = new FrameResponse($frame);
}
}
+
+ $this->extractionImageIds = isset($page['extraction_image_ids']) && is_array($page['extraction_image_ids'])
+ ? $page['extraction_image_ids']
+ : [];
}
/**
@@ -63,4 +72,12 @@ public function getFrames(): array
{
return $this->frames;
}
+
+ /**
+ * @return string[]
+ */
+ public function getExtractionImageIds(): array
+ {
+ return $this->extractionImageIds;
+ }
}
diff --git a/src/DocScan/Session/Retrieve/ResourceContainer.php b/src/DocScan/Session/Retrieve/ResourceContainer.php
index 5cc26097..dd0d07c3 100644
--- a/src/DocScan/Session/Retrieve/ResourceContainer.php
+++ b/src/DocScan/Session/Retrieve/ResourceContainer.php
@@ -31,6 +31,11 @@ class ResourceContainer
*/
private $shareCodes = [];
+ /**
+ * @var ApplicantProfileResourceResponse[]
+ */
+ private $applicantProfiles = [];
+
/**
* ResourceContainer constructor.
* @param array $resources
@@ -56,6 +61,10 @@ public function __construct(array $resources)
if (isset($resources['share_codes'])) {
$this->shareCodes = $this->parseShareCodes($resources['share_codes']);
}
+
+ if (isset($resources['applicant_profiles'])) {
+ $this->applicantProfiles = $this->parseApplicantProfiles($resources['applicant_profiles']);
+ }
}
/**
@@ -178,6 +187,14 @@ public function getShareCodes(): array
return $this->shareCodes;
}
+ /**
+ * @return ApplicantProfileResourceResponse[]
+ */
+ public function getApplicantProfiles(): array
+ {
+ return $this->applicantProfiles;
+ }
+
/**
* @param array> $shareCodes
* @return ShareCodeResourceResponse[]
@@ -191,6 +208,19 @@ private function parseShareCodes(array $shareCodes): array
return $parsedShareCodes;
}
+ /**
+ * @param array> $applicantProfiles
+ * @return ApplicantProfileResourceResponse[]
+ */
+ private function parseApplicantProfiles(array $applicantProfiles): array
+ {
+ $parsedApplicantProfiles = [];
+ foreach ($applicantProfiles as $applicantProfile) {
+ $parsedApplicantProfiles[] = new ApplicantProfileResourceResponse($applicantProfile);
+ }
+ return $parsedApplicantProfiles;
+ }
+
/**
* @param string $class
* @return mixed[]
diff --git a/src/DocScan/Session/Retrieve/TaskRecommendationReasonResponse.php b/src/DocScan/Session/Retrieve/TaskRecommendationReasonResponse.php
new file mode 100644
index 00000000..c365b7cc
--- /dev/null
+++ b/src/DocScan/Session/Retrieve/TaskRecommendationReasonResponse.php
@@ -0,0 +1,44 @@
+ $reason
+ */
+ public function __construct(array $reason)
+ {
+ $this->value = $reason['value'] ?? null;
+ $this->detail = $reason['detail'] ?? null;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getValue(): ?string
+ {
+ return $this->value;
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getDetail(): ?string
+ {
+ return $this->detail;
+ }
+}
diff --git a/src/DocScan/Session/Retrieve/TaskRecommendationResponse.php b/src/DocScan/Session/Retrieve/TaskRecommendationResponse.php
new file mode 100644
index 00000000..9e4ffa72
--- /dev/null
+++ b/src/DocScan/Session/Retrieve/TaskRecommendationResponse.php
@@ -0,0 +1,47 @@
+ $recommendation
+ */
+ public function __construct(array $recommendation)
+ {
+ $this->value = $recommendation['value'] ?? null;
+
+ if (isset($recommendation['reason'])) {
+ $this->reason = new TaskRecommendationReasonResponse($recommendation['reason']);
+ }
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getValue(): ?string
+ {
+ return $this->value;
+ }
+
+ /**
+ * @return TaskRecommendationReasonResponse|null
+ */
+ public function getReason(): ?TaskRecommendationReasonResponse
+ {
+ return $this->reason;
+ }
+}
diff --git a/src/DocScan/Session/Retrieve/TaskResponse.php b/src/DocScan/Session/Retrieve/TaskResponse.php
index e824cc51..324d8266 100644
--- a/src/DocScan/Session/Retrieve/TaskResponse.php
+++ b/src/DocScan/Session/Retrieve/TaskResponse.php
@@ -5,6 +5,7 @@
namespace Yoti\DocScan\Session\Retrieve;
use Yoti\DocScan\Constants;
+use Yoti\Exception\DateTimeException;
use Yoti\Util\DateTime;
class TaskResponse
@@ -44,9 +45,15 @@ class TaskResponse
*/
private $generatedMedia = [];
+ /**
+ * @var TaskRecommendationResponse|null
+ */
+ private $recommendation;
+
/**
* TaskResponse constructor.
* @param array $task
+ * @throws DateTimeException
*/
public function __construct(array $task)
{
@@ -67,6 +74,10 @@ public function __construct(array $task)
if (isset($task['generated_media'])) {
$this->generatedMedia = $this->parseGeneratedMedia($task['generated_media']);
}
+
+ if (isset($task['recommendation'])) {
+ $this->recommendation = new TaskRecommendationResponse($task['recommendation']);
+ }
}
/**
@@ -161,6 +172,14 @@ public function getGeneratedMedia(): array
return $this->generatedMedia;
}
+ /**
+ * @return TaskRecommendationResponse|null
+ */
+ public function getRecommendation(): ?TaskRecommendationResponse
+ {
+ return $this->recommendation;
+ }
+
/**
* @return GeneratedCheckResponse[]
*/
diff --git a/tests/DocScan/Session/Create/ApplicantProfileBuilderTest.php b/tests/DocScan/Session/Create/ApplicantProfileBuilderTest.php
new file mode 100644
index 00000000..bb000cf3
--- /dev/null
+++ b/tests/DocScan/Session/Create/ApplicantProfileBuilderTest.php
@@ -0,0 +1,142 @@
+withFullName(self::SOME_FULL_NAME)
+ ->build();
+
+ $this->assertEquals(self::SOME_FULL_NAME, $profile->getFullName());
+ }
+
+ /**
+ * @test
+ * @covers ::build
+ * @covers ::withDateOfBirth
+ * @covers \Yoti\DocScan\Session\Create\ApplicantProfile::__construct
+ * @covers \Yoti\DocScan\Session\Create\ApplicantProfile::getDateOfBirth
+ */
+ public function shouldBuildWithDateOfBirth()
+ {
+ $profile = (new ApplicantProfileBuilder())
+ ->withDateOfBirth(self::SOME_DATE_OF_BIRTH)
+ ->build();
+
+ $this->assertEquals(self::SOME_DATE_OF_BIRTH, $profile->getDateOfBirth());
+ }
+
+ /**
+ * @test
+ * @covers ::build
+ * @covers ::withNamePrefix
+ * @covers \Yoti\DocScan\Session\Create\ApplicantProfile::__construct
+ * @covers \Yoti\DocScan\Session\Create\ApplicantProfile::getNamePrefix
+ */
+ public function shouldBuildWithNamePrefix()
+ {
+ $profile = (new ApplicantProfileBuilder())
+ ->withNamePrefix(self::SOME_NAME_PREFIX)
+ ->build();
+
+ $this->assertEquals(self::SOME_NAME_PREFIX, $profile->getNamePrefix());
+ }
+
+ /**
+ * @test
+ * @covers ::build
+ * @covers ::withStructuredPostalAddress
+ * @covers \Yoti\DocScan\Session\Create\ApplicantProfile::__construct
+ * @covers \Yoti\DocScan\Session\Create\ApplicantProfile::getStructuredPostalAddress
+ */
+ public function shouldBuildWithStructuredPostalAddress()
+ {
+ $address = (new StructuredPostalAddressBuilder())
+ ->withBuildingNumber('74')
+ ->withPostalCode('E143RN')
+ ->build();
+
+ $profile = (new ApplicantProfileBuilder())
+ ->withStructuredPostalAddress($address)
+ ->build();
+
+ $this->assertEquals('74', $profile->getStructuredPostalAddress()->getBuildingNumber());
+ $this->assertEquals('E143RN', $profile->getStructuredPostalAddress()->getPostalCode());
+ }
+
+ /**
+ * @test
+ * @covers ::build
+ * @covers \Yoti\DocScan\Session\Create\ApplicantProfile::jsonSerialize
+ */
+ public function shouldCorrectlySerializeWithAllProperties()
+ {
+ $address = (new StructuredPostalAddressBuilder())
+ ->withAddressFormat(1)
+ ->withBuildingNumber('74')
+ ->withAddressLine1('AddressLine1')
+ ->withTownCity('CityName')
+ ->withPostalCode('E143RN')
+ ->withCountryIso('GBR')
+ ->withCountry('United Kingdom')
+ ->build();
+
+ $profile = (new ApplicantProfileBuilder())
+ ->withFullName(self::SOME_FULL_NAME)
+ ->withDateOfBirth(self::SOME_DATE_OF_BIRTH)
+ ->withNamePrefix(self::SOME_NAME_PREFIX)
+ ->withStructuredPostalAddress($address)
+ ->build();
+
+ $json = json_encode($profile);
+
+ $this->assertStringContainsString('"full_name":"John Doe"', $json);
+ $this->assertStringContainsString('"date_of_birth":"1988-11-02"', $json);
+ $this->assertStringContainsString('"name_prefix":"Mr"', $json);
+ $this->assertStringContainsString('"structured_postal_address"', $json);
+ $this->assertStringContainsString('"building_number":"74"', $json);
+ $this->assertStringContainsString('"country_iso":"GBR"', $json);
+ }
+
+ /**
+ * @test
+ * @covers ::build
+ * @covers \Yoti\DocScan\Session\Create\ApplicantProfile::jsonSerialize
+ */
+ public function shouldSerializeWithoutNullValues()
+ {
+ $profile = (new ApplicantProfileBuilder())
+ ->withFullName(self::SOME_FULL_NAME)
+ ->build();
+
+ $this->assertJsonStringEqualsJsonString(
+ json_encode([
+ 'full_name' => self::SOME_FULL_NAME,
+ ]),
+ json_encode($profile)
+ );
+ }
+}
diff --git a/tests/DocScan/Session/Create/ResourceCreationContainerBuilderTest.php b/tests/DocScan/Session/Create/ResourceCreationContainerBuilderTest.php
new file mode 100644
index 00000000..4ad23b4d
--- /dev/null
+++ b/tests/DocScan/Session/Create/ResourceCreationContainerBuilderTest.php
@@ -0,0 +1,93 @@
+withFullName('John Doe')
+ ->withDateOfBirth('1988-11-02')
+ ->build();
+
+ $container = (new ResourceCreationContainerBuilder())
+ ->withApplicantProfile($applicantProfile)
+ ->build();
+
+ $this->assertEquals($applicantProfile, $container->getApplicantProfile());
+ $this->assertEquals('John Doe', $container->getApplicantProfile()->getFullName());
+ $this->assertEquals('1988-11-02', $container->getApplicantProfile()->getDateOfBirth());
+ }
+
+ /**
+ * @test
+ * @covers ::build
+ * @covers \Yoti\DocScan\Session\Create\ResourceCreationContainer::jsonSerialize
+ */
+ public function shouldCorrectlySerializeApplicantProfile()
+ {
+ $address = (new StructuredPostalAddressBuilder())
+ ->withAddressFormat(1)
+ ->withBuildingNumber('74')
+ ->withAddressLine1('AddressLine1')
+ ->withTownCity('CityName')
+ ->withPostalCode('E143RN')
+ ->withCountryIso('GBR')
+ ->withCountry('United Kingdom')
+ ->build();
+
+ $applicantProfile = (new ApplicantProfileBuilder())
+ ->withFullName('John Doe')
+ ->withDateOfBirth('1988-11-02')
+ ->withNamePrefix('Mr')
+ ->withStructuredPostalAddress($address)
+ ->build();
+
+ $container = (new ResourceCreationContainerBuilder())
+ ->withApplicantProfile($applicantProfile)
+ ->build();
+
+ $json = json_encode($container);
+
+ $this->assertStringContainsString('"applicant_profile"', $json);
+ $this->assertStringContainsString('"full_name":"John Doe"', $json);
+ $this->assertStringContainsString('"date_of_birth":"1988-11-02"', $json);
+ $this->assertStringContainsString('"name_prefix":"Mr"', $json);
+ $this->assertStringContainsString('"building_number":"74"', $json);
+ $this->assertStringContainsString('"country_iso":"GBR"', $json);
+ }
+
+ /**
+ * @test
+ * @covers ::build
+ * @covers \Yoti\DocScan\Session\Create\ResourceCreationContainer::jsonSerialize
+ */
+ public function shouldSerializeWithoutNullValues()
+ {
+ $container = (new ResourceCreationContainerBuilder())
+ ->build();
+
+ $this->assertJsonStringEqualsJsonString(
+ json_encode(new \stdClass()),
+ json_encode($container)
+ );
+ }
+}
diff --git a/tests/DocScan/Session/Create/SessionSpecificationBuilderTest.php b/tests/DocScan/Session/Create/SessionSpecificationBuilderTest.php
index 266e47e4..f1d274b2 100644
--- a/tests/DocScan/Session/Create/SessionSpecificationBuilderTest.php
+++ b/tests/DocScan/Session/Create/SessionSpecificationBuilderTest.php
@@ -9,6 +9,7 @@
use Yoti\DocScan\Session\Create\IbvOptions;
use Yoti\DocScan\Session\Create\ImportToken;
use Yoti\DocScan\Session\Create\NotificationConfig;
+use Yoti\DocScan\Session\Create\ResourceCreationContainer;
use Yoti\DocScan\Session\Create\SdkConfig;
use Yoti\DocScan\Session\Create\SessionSpecificationBuilder;
use Yoti\DocScan\Session\Create\Task\RequestedTask;
@@ -73,6 +74,11 @@ class SessionSpecificationBuilderTest extends TestCase
*/
private $importTokenMock;
+ /**
+ * @var ResourceCreationContainer
+ */
+ private $resourcesMock;
+
public function setup(): void
{
$this->sdkConfigMock = $this->createMock(SdkConfig::class);
@@ -94,6 +100,11 @@ public function setup(): void
$this->importTokenMock = $this->createMock(ImportToken::class);
+ $this->resourcesMock = $this->createMock(ResourceCreationContainer::class);
+ $this->resourcesMock
+ ->method('jsonSerialize')
+ ->willReturn((object)['applicant_profile' => (object)['full_name' => 'John Doe']]);
+
$this->subject = (object)[1 => 'some'];
$this->identityProfileRequirements = (object)[
@@ -605,4 +616,58 @@ public function shouldReturnCorrectJsonStringWithAdvancedIdentityProfileRequirem
json_encode($sessionSpecification)
);
}
+
+ /**
+ * @test
+ * @covers \Yoti\DocScan\Session\Create\SessionSpecification::getResources
+ * @covers \Yoti\DocScan\Session\Create\SessionSpecification::__construct
+ * @covers \Yoti\DocScan\Session\Create\SessionSpecificationBuilder::withResources
+ * @covers \Yoti\DocScan\Session\Create\SessionSpecificationBuilder::build
+ */
+ public function shouldBuildWithResources()
+ {
+ $sessionSpecificationResult = (new SessionSpecificationBuilder())
+ ->withResources($this->resourcesMock)
+ ->build();
+
+ $this->assertEquals($this->resourcesMock, $sessionSpecificationResult->getResources());
+ }
+
+ /**
+ * @test
+ * @covers \Yoti\DocScan\Session\Create\SessionSpecification::getResources
+ * @covers \Yoti\DocScan\Session\Create\SessionSpecification::__construct
+ * @covers \Yoti\DocScan\Session\Create\SessionSpecificationBuilder::build
+ */
+ public function shouldNotImplicitlySetAValueForResources()
+ {
+ $sessionSpecificationResult = (new SessionSpecificationBuilder())
+ ->build();
+
+ $this->assertNull($sessionSpecificationResult->getResources());
+ }
+
+ /**
+ * @test
+ * @covers \Yoti\DocScan\Session\Create\SessionSpecification::jsonSerialize
+ * @covers \Yoti\DocScan\Session\Create\SessionSpecificationBuilder::withResources
+ * @covers \Yoti\DocScan\Session\Create\SessionSpecificationBuilder::build
+ */
+ public function shouldReturnCorrectJsonStringWithResources()
+ {
+ $sessionSpecification = (new SessionSpecificationBuilder())
+ ->withResources($this->resourcesMock)
+ ->build();
+
+ $this->assertJsonStringEqualsJsonString(
+ json_encode([
+ 'requested_checks' => [],
+ 'requested_tasks' => [],
+ 'required_documents' => [],
+ 'create_identity_profile_preview' => false,
+ 'resources' => $this->resourcesMock,
+ ]),
+ json_encode($sessionSpecification)
+ );
+ }
}
diff --git a/tests/DocScan/Session/Create/StructuredPostalAddressBuilderTest.php b/tests/DocScan/Session/Create/StructuredPostalAddressBuilderTest.php
new file mode 100644
index 00000000..ad4f6a80
--- /dev/null
+++ b/tests/DocScan/Session/Create/StructuredPostalAddressBuilderTest.php
@@ -0,0 +1,121 @@
+withAddressFormat(self::SOME_ADDRESS_FORMAT)
+ ->withBuildingNumber(self::SOME_BUILDING_NUMBER)
+ ->withAddressLine1(self::SOME_ADDRESS_LINE_1)
+ ->withTownCity(self::SOME_TOWN_CITY)
+ ->withPostalCode(self::SOME_POSTAL_CODE)
+ ->withCountryIso(self::SOME_COUNTRY_ISO)
+ ->withCountry(self::SOME_COUNTRY)
+ ->withFormattedAddress(self::SOME_FORMATTED_ADDRESS)
+ ->build();
+
+ $this->assertEquals(self::SOME_ADDRESS_FORMAT, $address->getAddressFormat());
+ $this->assertEquals(self::SOME_BUILDING_NUMBER, $address->getBuildingNumber());
+ $this->assertEquals(self::SOME_ADDRESS_LINE_1, $address->getAddressLine1());
+ $this->assertEquals(self::SOME_TOWN_CITY, $address->getTownCity());
+ $this->assertEquals(self::SOME_POSTAL_CODE, $address->getPostalCode());
+ $this->assertEquals(self::SOME_COUNTRY_ISO, $address->getCountryIso());
+ $this->assertEquals(self::SOME_COUNTRY, $address->getCountry());
+ $this->assertEquals(self::SOME_FORMATTED_ADDRESS, $address->getFormattedAddress());
+ }
+
+ /**
+ * @test
+ * @covers ::build
+ * @covers \Yoti\DocScan\Session\Create\StructuredPostalAddress::jsonSerialize
+ */
+ public function shouldCorrectlySerialize()
+ {
+ $address = (new StructuredPostalAddressBuilder())
+ ->withAddressFormat(self::SOME_ADDRESS_FORMAT)
+ ->withBuildingNumber(self::SOME_BUILDING_NUMBER)
+ ->withAddressLine1(self::SOME_ADDRESS_LINE_1)
+ ->withTownCity(self::SOME_TOWN_CITY)
+ ->withPostalCode(self::SOME_POSTAL_CODE)
+ ->withCountryIso(self::SOME_COUNTRY_ISO)
+ ->withCountry(self::SOME_COUNTRY)
+ ->withFormattedAddress(self::SOME_FORMATTED_ADDRESS)
+ ->build();
+
+ $this->assertJsonStringEqualsJsonString(
+ json_encode([
+ 'address_format' => self::SOME_ADDRESS_FORMAT,
+ 'building_number' => self::SOME_BUILDING_NUMBER,
+ 'address_line1' => self::SOME_ADDRESS_LINE_1,
+ 'town_city' => self::SOME_TOWN_CITY,
+ 'postal_code' => self::SOME_POSTAL_CODE,
+ 'country_iso' => self::SOME_COUNTRY_ISO,
+ 'country' => self::SOME_COUNTRY,
+ 'formatted_address' => self::SOME_FORMATTED_ADDRESS,
+ ]),
+ json_encode($address)
+ );
+ }
+
+ /**
+ * @test
+ * @covers ::build
+ * @covers \Yoti\DocScan\Session\Create\StructuredPostalAddress::jsonSerialize
+ */
+ public function shouldSerializeWithoutNullValues()
+ {
+ $address = (new StructuredPostalAddressBuilder())
+ ->withBuildingNumber(self::SOME_BUILDING_NUMBER)
+ ->withPostalCode(self::SOME_POSTAL_CODE)
+ ->build();
+
+ $this->assertJsonStringEqualsJsonString(
+ json_encode([
+ 'building_number' => self::SOME_BUILDING_NUMBER,
+ 'postal_code' => self::SOME_POSTAL_CODE,
+ ]),
+ json_encode($address)
+ );
+ }
+}
diff --git a/tests/DocScan/Session/Retrieve/ApplicantProfileResourceResponseTest.php b/tests/DocScan/Session/Retrieve/ApplicantProfileResourceResponseTest.php
new file mode 100644
index 00000000..645deaf2
--- /dev/null
+++ b/tests/DocScan/Session/Retrieve/ApplicantProfileResourceResponseTest.php
@@ -0,0 +1,81 @@
+ self::SOME_ID,
+ 'source' => [
+ 'type' => self::SOME_SOURCE_TYPE,
+ ],
+ 'media' => [
+ 'id' => self::SOME_MEDIA_ID,
+ 'type' => self::SOME_MEDIA_TYPE,
+ 'created' => self::SOME_CREATED_AT,
+ 'last_updated' => self::SOME_LAST_UPDATED,
+ ],
+ 'created_at' => self::SOME_CREATED_AT,
+ 'last_updated' => self::SOME_LAST_UPDATED,
+ 'tasks' => [],
+ ];
+
+ $result = new ApplicantProfileResourceResponse($input);
+
+ $this->assertEquals(self::SOME_ID, $result->getId());
+ $this->assertNotNull($result->getSource());
+ $this->assertInstanceOf(MediaResponse::class, $result->getMedia());
+ $this->assertEquals(self::SOME_MEDIA_ID, $result->getMedia()->getId());
+ $this->assertEquals(self::SOME_MEDIA_TYPE, $result->getMedia()->getType());
+ $this->assertEquals(
+ DateTime::stringToDateTime(self::SOME_CREATED_AT),
+ $result->getCreatedAt()
+ );
+ $this->assertEquals(
+ DateTime::stringToDateTime(self::SOME_LAST_UPDATED),
+ $result->getLastUpdated()
+ );
+ $this->assertCount(0, $result->getTasks());
+ }
+
+ /**
+ * @test
+ * @covers ::__construct
+ */
+ public function shouldNotThrowExceptionWhenMissingValues()
+ {
+ $result = new ApplicantProfileResourceResponse([]);
+
+ $this->assertNull($result->getId());
+ $this->assertNull($result->getMedia());
+ $this->assertNull($result->getCreatedAt());
+ $this->assertNull($result->getLastUpdated());
+ $this->assertCount(0, $result->getTasks());
+ }
+}
diff --git a/tests/DocScan/Session/Retrieve/BreakdownResponseTest.php b/tests/DocScan/Session/Retrieve/BreakdownResponseTest.php
index dc92d2fd..7d2c9a30 100644
--- a/tests/DocScan/Session/Retrieve/BreakdownResponseTest.php
+++ b/tests/DocScan/Session/Retrieve/BreakdownResponseTest.php
@@ -25,11 +25,15 @@ class BreakdownResponseTest extends TestCase
],
];
+ private const SOME_PROCESS = 'AUTOMATED';
+ private const SOME_EXPERT_REVIEW_PROCESS = 'EXPERT_REVIEW';
+
/**
* @test
* @covers ::__construct
* @covers ::getSubCheck
* @covers ::getResult
+ * @covers ::getProcess
* @covers ::getDetails
* @covers \Yoti\DocScan\Session\Retrieve\DetailsResponse::__construct
* @covers \Yoti\DocScan\Session\Retrieve\DetailsResponse::getName
@@ -40,6 +44,7 @@ public function shouldBuildCorrectly()
$input = [
'sub_check' => self::SOME_SUB_CHECK,
'result' => self::SOME_RESULT,
+ 'process' => self::SOME_PROCESS,
'details' => self::SOME_DETAILS,
];
@@ -47,6 +52,7 @@ public function shouldBuildCorrectly()
$this->assertEquals(self::SOME_SUB_CHECK, $result->getSubCheck());
$this->assertEquals(self::SOME_RESULT, $result->getResult());
+ $this->assertEquals(self::SOME_PROCESS, $result->getProcess());
$details = $result->getDetails();
for ($i = 0; $i < count(self::SOME_DETAILS); $i++) {
@@ -61,6 +67,7 @@ public function shouldBuildCorrectly()
* @covers ::__construct
* @covers ::getSubCheck
* @covers ::getResult
+ * @covers ::getProcess
* @covers ::getDetails
*/
public function shouldNotThrowExceptionWhenValuesAreMissing()
@@ -71,6 +78,19 @@ public function shouldNotThrowExceptionWhenValuesAreMissing()
$this->assertNull($result->getSubCheck());
$this->assertNull($result->getResult());
+ $this->assertNull($result->getProcess());
$this->assertCount(0, $result->getDetails());
}
+
+ /**
+ * @test
+ * @covers ::__construct
+ * @covers ::getProcess
+ */
+ public function shouldExposeExpertReviewProcessValue()
+ {
+ $result = new BreakdownResponse(['process' => self::SOME_EXPERT_REVIEW_PROCESS]);
+
+ $this->assertEquals(self::SOME_EXPERT_REVIEW_PROCESS, $result->getProcess());
+ }
}
diff --git a/tests/DocScan/Session/Retrieve/PageResponseTest.php b/tests/DocScan/Session/Retrieve/PageResponseTest.php
index 91306f12..063e0628 100644
--- a/tests/DocScan/Session/Retrieve/PageResponseTest.php
+++ b/tests/DocScan/Session/Retrieve/PageResponseTest.php
@@ -53,7 +53,26 @@ public function testGetFrames()
]);
$this->assertCount(2, $pageResponse->getFrames());
- $this->containsOnlyInstancesOf(FrameResponse::class, $pageResponse->getFrames());
+ $this->assertContainsOnlyInstancesOf(FrameResponse::class, $pageResponse->getFrames());
+ }
+
+ /**
+ * @covers ::__construct
+ * @covers ::getExtractionImageIds
+ */
+ public function testGetExtractionImageIds()
+ {
+ $extractionImageIds = [
+ '066a9372-0a52-4fe4-a026-866f8aee6fcb',
+ '9b0c9c0a-ff30-41ed-815b-d95d63271d45',
+ ];
+
+ $pageResponse = new PageResponse([
+ 'extraction_image_ids' => $extractionImageIds,
+ ]);
+
+ $this->assertCount(2, $pageResponse->getExtractionImageIds());
+ $this->assertEquals($extractionImageIds, $pageResponse->getExtractionImageIds());
}
/**
@@ -67,5 +86,6 @@ public function shouldNotThrowExceptionWhenMissingValues()
$this->assertNull($result->getCaptureMethod());
$this->assertNull($result->getMedia());
$this->assertEquals([], $result->getFrames());
+ $this->assertEquals([], $result->getExtractionImageIds());
}
}
diff --git a/tests/DocScan/Session/Retrieve/ResourceContainerTest.php b/tests/DocScan/Session/Retrieve/ResourceContainerTest.php
index 48dba28d..f73beb81 100644
--- a/tests/DocScan/Session/Retrieve/ResourceContainerTest.php
+++ b/tests/DocScan/Session/Retrieve/ResourceContainerTest.php
@@ -4,6 +4,7 @@
namespace Yoti\Test\DocScan\Session\Retrieve;
+use Yoti\DocScan\Session\Retrieve\ApplicantProfileResourceResponse;
use Yoti\DocScan\Session\Retrieve\ResourceContainer;
use Yoti\DocScan\Session\Retrieve\ShareCodeResourceResponse;
use Yoti\DocScan\Session\Retrieve\StaticLivenessResourceResponse;
@@ -53,7 +54,10 @@ public function shouldBuildCorrectly()
'share_codes' => [
['id' => 'share-code-1'],
['id' => 'share-code-2'],
- ]
+ ],
+ 'applicant_profiles' => [
+ ['id' => 'applicant-profile-1'],
+ ],
];
$result = new ResourceContainer($input);
@@ -65,6 +69,7 @@ public function shouldBuildCorrectly()
$this->assertCount(2, $result->getSupplementaryDocuments());
$this->assertCount(1, $result->getFaceCapture());
$this->assertCount(2, $result->getShareCodes());
+ $this->assertCount(1, $result->getApplicantProfiles());
}
/**
@@ -78,6 +83,7 @@ public function shouldNotThrowExceptionWhenMissingValues()
$this->assertCount(0, $result->getIdDocuments());
$this->assertCount(0, $result->getLivenessCapture());
$this->assertCount(0, $result->getShareCodes());
+ $this->assertCount(0, $result->getApplicantProfiles());
}
/**
@@ -175,4 +181,42 @@ public function shouldParseShareCodes(): void
$this->assertEquals('share-code-1', $result->getShareCodes()[0]->getId());
$this->assertEquals('share-code-2', $result->getShareCodes()[1]->getId());
}
+
+ /**
+ * @test
+ * @covers ::parseApplicantProfiles
+ * @covers ::getApplicantProfiles
+ */
+ public function shouldParseApplicantProfiles(): void
+ {
+ $input = [
+ 'applicant_profiles' => [
+ [
+ 'id' => '3fa85f64-5717-4562-b3fc-2c963f66afa6',
+ 'source' => ['type' => 'END_USER'],
+ 'media' => [
+ 'id' => 'media-id-123',
+ 'type' => 'IMAGE',
+ 'created' => '2021-06-11T11:39:24Z',
+ 'last_updated' => '2021-06-11T11:39:24Z',
+ ],
+ 'created_at' => '2021-06-11T11:39:24Z',
+ 'last_updated' => '2021-06-11T11:39:24Z',
+ 'tasks' => [],
+ ],
+ ],
+ ];
+
+ $result = new ResourceContainer($input);
+
+ $this->assertCount(1, $result->getApplicantProfiles());
+ $this->assertContainsOnlyInstancesOf(
+ ApplicantProfileResourceResponse::class,
+ $result->getApplicantProfiles()
+ );
+ $this->assertEquals(
+ '3fa85f64-5717-4562-b3fc-2c963f66afa6',
+ $result->getApplicantProfiles()[0]->getId()
+ );
+ }
}
diff --git a/tests/DocScan/Session/Retrieve/TaskRecommendationReasonResponseTest.php b/tests/DocScan/Session/Retrieve/TaskRecommendationReasonResponseTest.php
new file mode 100644
index 00000000..80c0a74c
--- /dev/null
+++ b/tests/DocScan/Session/Retrieve/TaskRecommendationReasonResponseTest.php
@@ -0,0 +1,48 @@
+ self::SOME_VALUE,
+ 'detail' => self::SOME_DETAIL,
+ ];
+
+ $result = new TaskRecommendationReasonResponse($input);
+
+ $this->assertEquals(self::SOME_VALUE, $result->getValue());
+ $this->assertEquals(self::SOME_DETAIL, $result->getDetail());
+ }
+
+ /**
+ * @test
+ * @covers ::__construct
+ */
+ public function shouldNotThrowExceptionWhenMissingValues()
+ {
+ $result = new TaskRecommendationReasonResponse([]);
+
+ $this->assertNull($result->getValue());
+ $this->assertNull($result->getDetail());
+ }
+}
diff --git a/tests/DocScan/Session/Retrieve/TaskRecommendationResponseTest.php b/tests/DocScan/Session/Retrieve/TaskRecommendationResponseTest.php
new file mode 100644
index 00000000..46c265b9
--- /dev/null
+++ b/tests/DocScan/Session/Retrieve/TaskRecommendationResponseTest.php
@@ -0,0 +1,55 @@
+ self::SOME_VALUE,
+ 'reason' => [
+ 'value' => self::SOME_REASON_VALUE,
+ 'detail' => self::SOME_REASON_DETAIL,
+ ],
+ ];
+
+ $result = new TaskRecommendationResponse($input);
+
+ $this->assertEquals(self::SOME_VALUE, $result->getValue());
+ $this->assertInstanceOf(TaskRecommendationReasonResponse::class, $result->getReason());
+ $this->assertEquals(self::SOME_REASON_VALUE, $result->getReason()->getValue());
+ $this->assertEquals(self::SOME_REASON_DETAIL, $result->getReason()->getDetail());
+ }
+
+ /**
+ * @test
+ * @covers ::__construct
+ */
+ public function shouldNotThrowExceptionWhenMissingValues()
+ {
+ $result = new TaskRecommendationResponse([]);
+
+ $this->assertNull($result->getValue());
+ $this->assertNull($result->getReason());
+ }
+}
diff --git a/tests/DocScan/Session/Retrieve/TaskResponseTest.php b/tests/DocScan/Session/Retrieve/TaskResponseTest.php
index 2b63366b..b3483119 100644
--- a/tests/DocScan/Session/Retrieve/TaskResponseTest.php
+++ b/tests/DocScan/Session/Retrieve/TaskResponseTest.php
@@ -7,6 +7,8 @@
use Yoti\DocScan\Session\Retrieve\GeneratedCheckResponse;
use Yoti\DocScan\Session\Retrieve\GeneratedMedia;
use Yoti\DocScan\Session\Retrieve\GeneratedTextDataCheckResponse;
+use Yoti\DocScan\Session\Retrieve\TaskRecommendationReasonResponse;
+use Yoti\DocScan\Session\Retrieve\TaskRecommendationResponse;
use Yoti\DocScan\Session\Retrieve\TaskResponse;
use Yoti\Test\TestCase;
use Yoti\Util\DateTime;
@@ -25,6 +27,9 @@ class TaskResponseTest extends TestCase
private const SOME_UNKNOWN_TYPE = 'someUnknownType';
private const ID_DOCUMENT_TEXT_DATA_CHECK = 'ID_DOCUMENT_TEXT_DATA_CHECK';
private const SUPPLEMENTARY_DOCUMENT_TEXT_DATA_CHECK = 'SUPPLEMENTARY_DOCUMENT_TEXT_DATA_CHECK';
+ private const SOME_RECOMMENDATION_VALUE = 'MUST_TRY_AGAIN';
+ private const SOME_RECOMMENDATION_REASON_VALUE = 'USER_ERROR';
+ private const SOME_RECOMMENDATION_REASON_DETAIL = 'NO_DOCUMENT';
/**
* @var TaskResponse
@@ -57,6 +62,13 @@ public function setup(): void
[],
[],
],
+ 'recommendation' => [
+ 'value' => self::SOME_RECOMMENDATION_VALUE,
+ 'reason' => [
+ 'value' => self::SOME_RECOMMENDATION_REASON_VALUE,
+ 'detail' => self::SOME_RECOMMENDATION_REASON_DETAIL,
+ ],
+ ],
]);
}
@@ -185,5 +197,22 @@ public function shouldNotThrowExceptionWhenAllMissingValuesExceptType()
$this->assertNull($result->getLastUpdated());
$this->assertCount(0, $result->getGeneratedChecks());
$this->assertCount(0, $result->getGeneratedMedia());
+ $this->assertNull($result->getRecommendation());
+ }
+
+ /**
+ * @test
+ * @covers ::__construct
+ * @covers ::getRecommendation
+ */
+ public function shouldReturnRecommendation()
+ {
+ $recommendation = $this->taskResponse->getRecommendation();
+
+ $this->assertInstanceOf(TaskRecommendationResponse::class, $recommendation);
+ $this->assertEquals(self::SOME_RECOMMENDATION_VALUE, $recommendation->getValue());
+ $this->assertInstanceOf(TaskRecommendationReasonResponse::class, $recommendation->getReason());
+ $this->assertEquals(self::SOME_RECOMMENDATION_REASON_VALUE, $recommendation->getReason()->getValue());
+ $this->assertEquals(self::SOME_RECOMMENDATION_REASON_DETAIL, $recommendation->getReason()->getDetail());
}
}