Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uml 2642 cant request more than one a day final #2243

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions service-api/app/features/context/Integration/LpaContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use DateInterval;
use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use DateTimeZone;
use Exception;
use Fig\Http\Message\StatusCodeInterface;
Expand Down Expand Up @@ -2785,6 +2786,8 @@ public function iProvideTheDetailsFromAValidPaperLPAWhichIHaveAlreadyAddedToMyAc
'Id' => $this->userLpaActorToken,
'ActorId' => $this->actorLpaId,
'UserId' => $this->userId,
'Updated' => (new DateTime('2020-01-01'))->format(DateTimeInterface::ATOM),
'DueBy' => (new DateTime('2020-01-01'))->format(DateTimeInterface::ATOM),
]
),
]
Expand Down Expand Up @@ -2812,15 +2815,18 @@ public function iProvideTheDetailsFromAValidPaperLPAWhichIHaveAlreadyAddedToMyAc

if ($this->container->get(FeatureEnabled::class)('save_older_lpa_requests')) {
$expectedResponse = [
'donor' => [
'donor' => [
'uId' => $this->lpa->donor->uId,
'firstname' => $this->lpa->donor->firstname,
'middlenames' => $this->lpa->donor->middlenames,
'surname' => $this->lpa->donor->surname,
],
'caseSubtype' => $this->lpa->caseSubtype,
'lpaActorToken' => $this->userLpaActorToken,
'activationKeyDueDate' => null,
'caseSubtype' => $this->lpa->caseSubtype,
'lpaActorToken' => $this->userLpaActorToken,
// would normally expect for this to be a string but this integration test intercepts before it's
// rendered to an error response.
'activationKeyDueDate' => new DateTime('2020-01-01'),
'activationKeyRequestedDate' => new DateTime('2020-01-01'),
];
} else {
$expectedResponse = [
Expand Down Expand Up @@ -2854,7 +2860,9 @@ public function iProvideTheDetailsFromAValidPaperLPAWhichIHaveAlreadyAddedToMyAc
*/
public function iProvideTheDetailsFromAValidPaperLPAWhichIHaveAlreadyRequestedAnActivationKeyFor(): void
{
$createdDate = (new DateTime())->modify('-14 days');
$createdDate = new DateTimeImmutable('-14 days');
$dueByDate = (new DateTimeImmutable('+9 days'))->format(DateTimeInterface::ATOM);
$updatedDate = (new DateTimeImmutable('-1 days'))->format(DateTimeInterface::ATOM);

$data = [
'reference_number' => (int) $this->lpaUid,
Expand Down Expand Up @@ -2897,6 +2905,8 @@ public function iProvideTheDetailsFromAValidPaperLPAWhichIHaveAlreadyRequestedAn
'ActorId' => $this->actorLpaId,
'UserId' => $this->userId,
'ActivateBy' => 123456789,
'DueBy' => $dueByDate,
'Updated' => $updatedDate,
]
),
]
Expand All @@ -2911,14 +2921,7 @@ public function iProvideTheDetailsFromAValidPaperLPAWhichIHaveAlreadyRequestedAn
$this->lpa
);

$codeExists = new stdClass();
$createdDate = (new DateTime())->modify('-14 days');

$activationKeyDueDate = DateTimeImmutable::createFromMutable($createdDate);
$activationKeyDueDate = $activationKeyDueDate
->add(new DateInterval('P10D'))
->format('Y-m-d');

$codeExists = new stdClass();
$codeExists->Created = $createdDate->format('Y-m-d');

$this->pactPostInteraction(
Expand All @@ -2933,14 +2936,15 @@ public function iProvideTheDetailsFromAValidPaperLPAWhichIHaveAlreadyRequestedAn
);

$expectedResponse = [
'donor' => [
'donor' => [
'uId' => $this->lpa->donor->uId,
'firstname' => $this->lpa->donor->firstname,
'middlenames' => $this->lpa->donor->middlenames,
'surname' => $this->lpa->donor->surname,
],
'caseSubtype' => $this->lpa->caseSubtype,
'activationKeyDueDate' => $activationKeyDueDate,
'caseSubtype' => $this->lpa->caseSubtype,
'activationKeyDueDate' => new DateTimeImmutable($dueByDate),
'activationKeyRequestedDate' => new DateTimeImmutable($updatedDate),
];

$addOlderLpa = $this->container->get(AddAccessForAllLpa::class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace App\DataAccess\DynamoDb;

use App\DataAccess\ValueObjects\DateTimeImmutable;
use Aws\DynamoDb\Marshaler;
use Aws\Result;
use DateTime;
use Exception;
use UnexpectedValueException;

Expand Down Expand Up @@ -67,7 +67,7 @@ private function extractData(array $resultItem, array $dateFields = []): array
$thisVal = $marshaler->unmarshalValue($value);

if (in_array($key, $dateFields)) {
$thisVal = new DateTime($thisVal);
$thisVal = new DateTimeImmutable($thisVal);
}

$item[$key] = $thisVal;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class UserLpaActorMap implements UserLpaActorMapInterface
{
use DynamoHydrateTrait;

private const DATE_FIELDS = ['Added', 'ActivatedOn', 'DueBy', 'Updated'];

public function __construct(
private DynamoDbClient $client,
private string $userLpaActorTable,
Expand All @@ -44,7 +46,7 @@ public function get(string $lpaActorToken): ?array
]
);

$codeData = $this->getData($result, ['Added']);
$codeData = $this->getData($result, self::DATE_FIELDS);

$codeData = !empty($codeData) ? $codeData : null;
if ($codeData === null) {
Expand Down Expand Up @@ -79,6 +81,7 @@ public function create(
'UserId' => ['S' => $userId],
'SiriusUid' => ['S' => $siriusUid],
'Added' => ['S' => $added->format(DateTimeInterface::ATOM)],
'Updated' => ['S' => $added->format(DateTimeInterface::ATOM)],
];

if ($actorId !== null) {
Expand Down Expand Up @@ -146,7 +149,7 @@ public function delete(string $lpaActorToken): array
]
);

return $this->getData($response);
return $this->getData($response, self::DATE_FIELDS);
}

/**
Expand All @@ -156,18 +159,19 @@ public function delete(string $lpaActorToken): array
*/
public function activateRecord(string $lpaActorToken, string $actorId, string $activationCode): array
{
$current = new DateTimeImmutable('now', new DateTimeZone('Etc/UTC'));
$current = new DateTimeImmutable('now', new DateTimeZone('Etc/UTC'));
$activatedTime = $current->format(DateTimeInterface::ATOM);

$response = $this->client->updateItem(
[
'TableName' => $this->userLpaActorTable,
'Key' => [
'TableName' => $this->userLpaActorTable,
'Key' => [
'Id' => [
'S' => $lpaActorToken,
],
],
'UpdateExpression' => 'set ActorId = :a, ActivationCode = :b, ActivatedOn = :c remove ActivateBy, DueBy',
'UpdateExpression'
=> 'set ActorId = :a, ActivationCode = :b, ActivatedOn = :c, Updated = :d remove ActivateBy, DueBy',
'ExpressionAttributeValues' => [
':a' => [
'N' => $actorId,
Expand All @@ -178,12 +182,15 @@ public function activateRecord(string $lpaActorToken, string $actorId, string $a
':c' => [
'S' => $activatedTime,
],
':d' => [
'S' => $activatedTime,
],
],
'ReturnValues' => 'ALL_NEW',
]
);

return $this->getData($response);
return $this->getData($response, self::DATE_FIELDS);
}

/**
Expand All @@ -206,7 +213,7 @@ public function getByUserId(string $userId): ?array
]
);

return $this->getDataCollection($result, ['Added']);
return $this->getDataCollection($result, self::DATE_FIELDS);
}

/**
Expand All @@ -220,7 +227,7 @@ public function updateRecord(
DateInterval $intervalTillDue,
?string $actorId,
): array {
$now = new DateTimeImmutable();
$now = new DateTimeImmutable('now', new DateTimeZone('Etc/UTC'));
$expiry = $now->add($expiryInterval);
$dueBy = $now->add($intervalTillDue);

Expand All @@ -231,20 +238,21 @@ public function updateRecord(
'S' => $lpaActorToken,
],
],
'UpdateExpression' => 'set ActivateBy = :a, DueBy = :b',
'UpdateExpression' => 'set ActivateBy = :a, DueBy = :b, Updated = :c',
'ExpressionAttributeValues' => [
':a' => ['N' => (string) $expiry->getTimestamp()],
':b' => ['S' => $dueBy->format(DateTimeInterface::ATOM)],
':c' => ['S' => $now->format(DateTimeInterface::ATOM)],
],
'ReturnValues' => 'ALL_NEW',
];

if ($actorId !== null) {
$updateRequest['UpdateExpression'] = $updateRequest['UpdateExpression'] . ', ActorId = :c';
$updateRequest['ExpressionAttributeValues'][':c'] = ['N' => $actorId];
$updateRequest['UpdateExpression'] = $updateRequest['UpdateExpression'] . ', ActorId = :d';
$updateRequest['ExpressionAttributeValues'][':d'] = ['N' => $actorId];
}

$response = $this->client->updateItem($updateRequest);
return $this->getData($response);
return $this->getData($response, self::DATE_FIELDS);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace App\DataAccess\ValueObjects;

use DateTimeImmutable as GlobalDateTimeImmutable;
use DateTimeInterface;
use JsonSerializable;

/**
* Simple wrapper class that ensures json_encode returns a nice string instead
* of a PHP array.
*/
class DateTimeImmutable extends GlobalDateTimeImmutable implements JsonSerializable
{
public function jsonSerialize(): mixed
{
return $this->format(DateTimeInterface::ATOM);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
use App\Exception\ApiException;
use App\Service\Features\FeatureEnabled;
use DateInterval;
use DateTime;
use DateTimeImmutable;
use DateTimeInterface;
use Psr\Log\LoggerInterface;

class AccessForAllLpaService
Expand All @@ -33,16 +34,16 @@ public function __construct(
*
* @param string $lpaId
* @param string $actorId
* @return DateTime|null
* @return DateTimeInterface|null
*/
public function hasActivationCode(string $lpaId, string $actorId): ?DateTime
public function hasActivationCode(string $lpaId, string $actorId): ?DateTimeInterface
{
$response = $this->actorCodes->checkActorHasCode($lpaId, $actorId);
if (is_null($response->getData()['Created'])) {
return null;
}

$createdDate = DateTime::createFromFormat('Y-m-d', $response->getData()['Created']);
$createdDate = DateTimeImmutable::createFromFormat('Y-m-d', $response->getData()['Created']);

$this->logger->notice(
'Activation key exists for actor {actorId} on LPA {lpaId}',
Expand Down
22 changes: 13 additions & 9 deletions service-api/app/src/App/src/Service/Lpa/AddAccessForAllLpa.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
use Exception;
use Psr\Log\LoggerInterface;
use App\Service\Features\FeatureEnabled;
use DateTimeInterface;

class AddAccessForAllLpa
{
private const CODE_ARRIVAL_INTERVAL = 'P10D';

/**
* @param FindActorInLpa $findActorInLpa
* @param LpaService $lpaService
Expand Down Expand Up @@ -69,20 +72,21 @@ private function existentCodeNotActivated(
(string) $resolvedActor['actor']['uId'],
);

if ($hasActivationCode instanceof DateTime) {
$activationKeyDueDate = DateTimeImmutable::createFromMutable($hasActivationCode);
if ($hasActivationCode instanceof DateTimeInterface) {
$activationKeyDueDate = DateTimeImmutable::createFromInterface($hasActivationCode);
$activationKeyDueDate = $activationKeyDueDate
->add(new DateInterval('P10D'))
->add(new DateInterval(self::CODE_ARRIVAL_INTERVAL))
->format('Y-m-d');
}
}

throw new BadRequestException(
'Activation key already requested for LPA',
[
'donor' => $lpaAddedData['donor'],
'caseSubtype' => $lpaAddedData['caseSubtype'],
'activationKeyDueDate' => $activationKeyDueDate,
'donor' => $lpaAddedData['donor'],
'caseSubtype' => $lpaAddedData['caseSubtype'],
'activationKeyDueDate' => $activationKeyDueDate,
'activationKeyRequestedDate' => $lpaAddedData['activationKeyRequestedDate'],
],
);
}
Expand Down Expand Up @@ -112,10 +116,10 @@ private function processActivationCode(
(string) $resolvedActor['actor']['uId']
);

if ($hasActivationCode instanceof DateTime) {
$activationKeyDueDate = DateTimeImmutable::createFromMutable($hasActivationCode);
if ($hasActivationCode instanceof DateTimeInterface) {
$activationKeyDueDate = DateTimeImmutable::createFromInterface($hasActivationCode);
$activationKeyDueDate = $activationKeyDueDate
->add(new DateInterval('P10D'))
->add(new DateInterval(self::CODE_ARRIVAL_INTERVAL))
->format('Y-m-d');

throw new BadRequestException(
Expand Down
12 changes: 7 additions & 5 deletions service-api/app/src/App/src/Service/Lpa/LpaAlreadyAdded.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,24 @@ private function populateLpaRecord(array $record, string $userId): ?array
}

$response = [
'donor' => [
'donor' => [
'uId' => $lpa['lpa']['donor']['uId'],
'firstname' => $lpa['lpa']['donor']['firstname'],
'middlenames' => $lpa['lpa']['donor']['middlenames'],
'surname' => $lpa['lpa']['donor']['surname'],
],
'caseSubtype' => $lpa['lpa']['caseSubtype'],
'lpaActorToken' => $record['Id'],
'activationKeyDueDate' => $lpa['activationKeyDueDate'] ?? null,
'caseSubtype' => $lpa['lpa']['caseSubtype'],
'lpaActorToken' => $record['Id'],
'activationKeyDueDate' => $lpa['activationKeyDueDate'] ?? null,
'activationKeyRequestedDate' => $lpa['activationKeyRequestedDate'] ?? null,
];

if (array_key_exists('ActivateBy', $record)) {
$response['notActivated'] = true;
}

return $response;
// filtering removes all falsy values - including null.
return array_filter($response);
}

/**
Expand Down
Loading