-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: cannot sign declaration unless op-adm for org has logged in (#364)
* feat: cannot sign declaration unless op-adm has logged in * chore: refactors and unit tests * chore: removed unused import * fix: locked down access to query * fix: local.php.dist missing quote and tdy up
- Loading branch information
Showing
11 changed files
with
968 additions
and
2,305 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
app/api/module/Api/src/Domain/QueryHandler/User/OperatorAdminForOrganisationHasLoggedIn.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
<?php declare(strict_types=1); | ||
|
||
namespace Dvsa\Olcs\Api\Domain\QueryHandler\User; | ||
|
||
use Dvsa\Olcs\Api\Domain\Exception\BadRequestException; | ||
use Dvsa\Olcs\Api\Domain\Exception\RuntimeException; | ||
use Dvsa\Olcs\Api\Domain\Query\User\UserListSelfserve as ListDto; | ||
use Dvsa\Olcs\Api\Domain\QueryHandler\AbstractQueryHandler; | ||
use Dvsa\Olcs\Api\Domain\Repository; | ||
use Dvsa\Olcs\Api\Entity; | ||
use Dvsa\Olcs\Transfer\Query\QueryInterface; | ||
use Dvsa\Olcs\Transfer\Query\User\OperatorAdminForOrganisationHasLoggedIn as Qry; | ||
|
||
class OperatorAdminForOrganisationHasLoggedIn extends AbstractQueryHandler | ||
{ | ||
public const DEFAULT_LAST_LOGGED_IN_FROM = '1970-01-01'; | ||
|
||
protected $repoServiceName = Repository\User::class; | ||
|
||
/** | ||
* Handle query | ||
* | ||
* @param QueryInterface $query query | ||
* | ||
* @throws BadRequestException|RuntimeException | ||
*/ | ||
public function handleQuery(QueryInterface $query): array | ||
{ | ||
if (!$query instanceof Qry) { | ||
throw new BadRequestException('Expected instance of: ' . Qry::class); | ||
} | ||
|
||
if (empty($query->getOrganisation())) { | ||
throw new BadRequestException('Organisation ID is required'); | ||
} | ||
|
||
$repo = $this->getRepo(Repository\User::class); | ||
|
||
$params = [ | ||
'organisation' => $query->getOrganisation(), | ||
'roles' => [Entity\User\Role::ROLE_OPERATOR_ADMIN], | ||
'page' => 1, | ||
'limit' => 1, | ||
'sort' => 'id', | ||
'order' => 'DESC', | ||
]; | ||
|
||
$lastLoginDate = static::DEFAULT_LAST_LOGGED_IN_FROM; | ||
if (!empty($query->getLastLoggedInFrom())) { | ||
$lastLoginDate = $query->getLastLoggedInFrom(); | ||
} | ||
|
||
$params['lastLoggedInFrom'] = $lastLoginDate; | ||
|
||
$userListDto = ListDto::create($params); | ||
|
||
$result = [ | ||
'organisation' => (int) $query->getOrganisation(), | ||
'lastLoggedInFrom' => $lastLoginDate, | ||
'operatorAdminHasLoggedIn' => false, | ||
]; | ||
|
||
if ($repo->fetchCount($userListDto) > 0) { | ||
$result['operatorAdminHasLoggedIn'] = true; | ||
} | ||
|
||
return $result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
...t/module/Api/src/Domain/QueryHandler/User/OperatorAdminForOrganisationHasLoggedInTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
<?php | ||
|
||
namespace Dvsa\OlcsTest\Api\Domain\QueryHandler\User; | ||
|
||
use DateTimeImmutable; | ||
use Dvsa\Olcs\Api\Domain\Query\User\UserListSelfserve as ListDto; | ||
use Dvsa\Olcs\Api\Domain\QueryHandler\User\OperatorAdminForOrganisationHasLoggedIn as QueryHandler; | ||
use Dvsa\Olcs\Api\Domain\Repository; | ||
use Dvsa\Olcs\Api\Entity; | ||
use Dvsa\Olcs\Transfer\Query\QueryInterface; | ||
use Dvsa\Olcs\Transfer\Query\User\OperatorAdminForOrganisationHasLoggedIn as Query; | ||
use Dvsa\OlcsTest\Api\Domain\QueryHandler\QueryHandlerTestCase; | ||
use LmcRbacMvc\Service\AuthorizationService; | ||
use Mockery as m; | ||
|
||
class OperatorAdminForOrganisationHasLoggedInTest extends QueryHandlerTestCase | ||
{ | ||
public function setUp(): void | ||
{ | ||
$this->sut = new QueryHandler(); | ||
$this->mockRepo(Repository\User::class, Repository\User::class); | ||
|
||
$this->mockedSmServices = [ | ||
AuthorizationService::class => m::mock(AuthorizationService::class) | ||
]; | ||
|
||
parent::setUp(); | ||
} | ||
|
||
public function dpHandleQuery_OrganisationHasOperatorAdminsWhoHaveLoggedIn(): array | ||
{ | ||
return [ | ||
'HasLoggedIn' => [ | ||
'fetchCountResult' => 1, | ||
'expectedOperatorAdminHasLoggedIn' => true, | ||
], | ||
'HasNotLoggedIn' => [ | ||
'fetchCountResult' => 0, | ||
'expectedOperatorAdminHasLoggedIn' => false, | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* @dataProvider dpHandleQuery_OrganisationHasOperatorAdminsWhoHaveLoggedIn | ||
*/ | ||
public function testHandleQuery_OrganisationHasOperatorAdminsWhoHaveLoggedIn(int $fetchCountResult, bool $expectedOperatorAdminHasLoggedIn): void | ||
{ | ||
$organisationId = 1; | ||
|
||
$query = Query::create(['organisation' => $organisationId]); | ||
|
||
$repo = $this->repoMap[Repository\User::class]; | ||
$repo->shouldReceive('fetchCount') | ||
->with(m::type(ListDto::class)) | ||
->andReturn($fetchCountResult); | ||
|
||
|
||
$result = $this->sut->handleQuery($query); | ||
$this->assertArrayHasKey('operatorAdminHasLoggedIn', $result); | ||
$this->assertEquals($expectedOperatorAdminHasLoggedIn, $result['operatorAdminHasLoggedIn']); | ||
} | ||
|
||
public function dpHandleQuery_UsesLastLoggedInFromFromQueryIfProvided(): array | ||
{ | ||
return [ | ||
'LastLoggedInFrom not specified' => [ | ||
'expectedLastLoggedInFrom' => QueryHandler::DEFAULT_LAST_LOGGED_IN_FROM, | ||
'query' => Query::create(['organisation' => 1]), | ||
], | ||
'LastLoggedInFrom specified' => [ | ||
'expectedLastLoggedInFrom' => $specifiedDate = '2020-01-01', | ||
'query' => Query::create(['organisation' => 1, 'lastLoggedInFrom' => $specifiedDate]), | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* @dataProvider dpHandleQuery_UsesLastLoggedInFromFromQueryIfProvided | ||
*/ | ||
public function testHandleQuery_UsesLastLoggedInFromFromQueryIfProvided(string $expectedLastLoggedInFrom, Query $query): void | ||
{ | ||
$repo = $this->repoMap[Repository\User::class]; | ||
$repo->shouldReceive('fetchCount') | ||
->withArgs(function (ListDto $dto) use ($expectedLastLoggedInFrom) { | ||
return $dto->getLastLoggedInFrom() === $expectedLastLoggedInFrom; | ||
}) | ||
->andReturn(0); | ||
|
||
$result = $this->sut->handleQuery($query); | ||
$this->assertArrayHasKey('lastLoggedInFrom', $result); | ||
$this->assertEquals($expectedLastLoggedInFrom, $result['lastLoggedInFrom']); | ||
} | ||
|
||
public function testHandleQuery_ResultContainsOrganisationIdFromQuery(): void | ||
{ | ||
$organisationId = 1; | ||
|
||
$query = Query::create(['organisation' => $organisationId]); | ||
|
||
$repo = $this->repoMap[Repository\User::class]; | ||
$repo->shouldReceive('fetchCount') | ||
->with(m::type(ListDto::class)) | ||
->andReturn(0); | ||
|
||
$result = $this->sut->handleQuery($query); | ||
$this->assertArrayHasKey('organisation', $result); | ||
$this->assertEquals($organisationId, $result['organisation']); | ||
} | ||
|
||
public function testHandleQuery_ThrowsExceptionIfOrganisationIdNotProvided(): void | ||
{ | ||
$this->expectExceptionMessage('Organisation ID is required'); | ||
$this->expectException(\Dvsa\Olcs\Api\Domain\Exception\BadRequestException::class); | ||
|
||
$this->sut->handleQuery(Query::create([])); | ||
} | ||
|
||
public function testHandleQuery_ThrowsExceptionIfQueryIsNotInstanceOfOperatorAdminForOrganisationHasLoggedIn(): void | ||
{ | ||
$this->expectExceptionMessage('Expected instance of: ' . Query::class); | ||
$this->expectException(\Dvsa\Olcs\Api\Domain\Exception\BadRequestException::class); | ||
|
||
$instance = new class() extends \stdClass implements QueryInterface { | ||
public function exchangeArray(array $array) | ||
{ | ||
// TODO: Implement exchangeArray() method. | ||
} | ||
|
||
public function getArrayCopy() | ||
{ | ||
// TODO: Implement getArrayCopy() method. | ||
} | ||
|
||
public static function create(array $data) | ||
{ | ||
// TODO: Implement create() method. | ||
} | ||
}; | ||
|
||
$this->sut->handleQuery($instance); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.