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

DDLS-348: Amend the registration so that users can't sign up more than once #1776

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
11 changes: 9 additions & 2 deletions api/app/src/Controller/PreRegistrationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ class PreRegistrationController extends RestController
public function __construct(
private PreRegistrationVerificationService $preRegistrationVerificationService,
private RestFormatter $formatter,
private EntityManagerInterface $em
private EntityManagerInterface $em,
) {
}

/**
* @Route("/delete", methods={"DELETE"})
*
* @Security("is_granted('ROLE_ADMIN')")
*
* @return array|JsonResponse
Expand Down Expand Up @@ -82,10 +83,15 @@ public function verify(Request $request, PreRegistrationVerificationService $ver
);

if (1 == count($verificationService->getLastMatchedDeputyNumbers())) {
if ($this->preRegistrationVerificationService->deputyHasNotSignedUpAlready()) {
$user->setIsPrimary(true);
} else {
throw new \RuntimeException(json_encode('Deputy has already registered for the service'), 464);
}

$user->setDeputyNo($verificationService->getLastMatchedDeputyNumbers()[0]);
$user->setDeputyUid($verificationService->getLastMatchedDeputyNumbers()[0]);
$user->setPreRegisterValidatedDate(new \DateTime());
$user->setIsPrimary(true);
$this->em->persist($user);
$this->em->flush();
} else {
Expand All @@ -98,6 +104,7 @@ public function verify(Request $request, PreRegistrationVerificationService $ver

/**
* @Route("/count", methods={"GET"})
*
* @Security("is_granted('ROLE_ADMIN')")
*/
public function userCount()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function isMultiDeputyCase(string $caseNumber): bool
return count($crMatches) > 1;
}

public function isSingleDeputyAccount(): bool
public function deputyHasNotSignedUpAlready(): bool
{
$deputyUid = $this->getLastMatchedDeputyNumbers()[0];
$existingDeputyAccounts = $this->userRepository->findBy(['deputyUid' => intval($deputyUid)]);
Expand Down
8 changes: 7 additions & 1 deletion api/app/src/Service/UserRegistrationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,10 @@ public function selfRegisterUser(SelfRegisterData $selfRegisterData)
$user->setPreRegisterValidatedDate(new \DateTime('now'));
$user->setRegistrationRoute(User::SELF_REGISTER);

if ($this->preRegistrationVerificationService->isSingleDeputyAccount()) {
if ($this->preRegistrationVerificationService->deputyHasNotSignedUpAlready()) {
$user->setIsPrimary(true);
} else {
throw new \RuntimeException(json_encode('Deputy has already registered for the service'), 464);
}
} else {
// A deputy could not be uniquely identified due to matching first name, last name and postcode across more than one deputy record
Expand Down Expand Up @@ -121,6 +123,10 @@ public function validateCoDeputy(SelfRegisterData $selfRegisterData)
$selfRegisterData->getPostcode()
);

if (!$this->preRegistrationVerificationService->deputyHasNotSignedUpAlready()) {
throw new \RuntimeException('Deputy has already registered for the service', 464);
}

// store case number in class property to access in retrieveCoDeputyUid exception
$this->selfRegisterCaseNumber = $selfRegisterData->getCaseNumber();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ trait SelfRegistrationTrait
private string $invalidClientLastnameError = "The client's last name you provided does not match our records.";
private string $deputyNotUniquelyIdentifiedError = "The information you've given us does not allow us to uniquely identify you as the deputy.\nPlease call 0115 934 2700 to make sure we have the correct record of your deputyship.";
private string $deputyAlreadyLinkedToCaseNumberError = 'You are already registered as a deputy for this case. Please check your case number and try again. If you have any questions, call our helpline on 0115 934 2700.';
private string $deputyAlreadyRegistered = 'You have already registered as a deputy. Please log in to your account to view this case. If you have any questions, call our helpline on 0115 934 2700.';
private string $reportingPeriodGreaterThanFifteenMonths = 'Check the end date: your reporting period cannot be more than 15 months';
private string $userEmail;
private string $coDeputyEmail;
Expand Down Expand Up @@ -100,7 +101,7 @@ private function fillInSelfRegistrationFieldsAndSubmit(
string $postcode,
string $clientFirstname,
string $clientLastname,
string $caseNumber
string $caseNumber,
) {
$this->fillInField('self_registration_firstname', $firstname);
$this->fillInField('self_registration_lastname', $lastname);
Expand Down Expand Up @@ -449,6 +450,14 @@ public function iShouldSeeADeputyAlreadyLinkedToCaseNumberError(): void
$this->assertOnErrorMessage($this->deputyAlreadyLinkedToCaseNumberError);
}

/**
* @Then I/they should see a 'deputy has already registered' error
*/
public function iShouldSeeADeputyHasAlreadyRegistered(): void
{
$this->assertOnErrorMessage($this->deputyAlreadyRegistered);
}

/**
* @Given /^I create a Lay Deputy user account for one of the deputies in the CSV that are not unique$/
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Feature: Lay Deputy Self Registration
And I should be on the Lay homepage
When I invite a Co-Deputy to the service who is already registered
Then they shouldn't be able to register to deputise for a client with already registered details
And they should see a 'deputy already linked to case number' error
And they should see a 'deputy has already registered' error

@super-admin
Scenario: A Lay user entering an invalid reporting period
Expand Down
61 changes: 54 additions & 7 deletions api/app/tests/Unit/Controller/PreRegistrationControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,12 @@ public function testVerifyPreRegistrationCoDeputyCannotSignUp()
]);
}

private function buildAndPersistPreRegistrationEntity(string $case, string $hybrid = 'SINGLE', string $deputyFirstname = 'test', string $deputySurname = 'admin'): PreRegistration
private function buildAndPersistPreRegistrationEntity(string $case, string $hybrid = 'SINGLE', string $deputyFirstname = 'test', string $deputySurname = 'admin', string $deputyuid = '700571111000'): PreRegistration
{
$preRegistration = new PreRegistration([
'Case' => $case,
'ClientSurname' => 'I should get deleted',
'DeputyUid' => '700571111000',
'DeputyUid' => $deputyuid,
'DeputyFirstname' => $deputyFirstname,
'DeputySurname' => $deputySurname,
'DeputyAddress1' => 'Victoria Road',
Expand All @@ -196,8 +196,8 @@ private function buildAndPersistPreRegistrationEntity(string $case, string $hybr

public function testDeputyUidSetWhenSingleMatchFound()
{
$this->buildAndPersistPreRegistrationEntity('17171717', 'SINGLE', 'test', 'deputy');
$this->buildAndPersistPreRegistrationEntity('28282828', 'SINGLE', 'test', 'deputy');
$this->buildAndPersistPreRegistrationEntity('17171717', 'SINGLE', 'test', 'deputy', '771177117711');
$this->buildAndPersistPreRegistrationEntity('28282828', 'SINGLE', 'test', 'deputy', '771177117711');
$this->fixtures()->flush();
$this->fixtures()->clear();

Expand All @@ -207,7 +207,8 @@ public function testDeputyUidSetWhenSingleMatchFound()
$loggedInUser = $this->fixtures()->clear()->getRepo('User')->find($this->loggedInUserId);

$loggedInUser->setDeputyNo(null);
$loggedInUser->setDeputyUid(0);
$loggedInUser->setDeputyUid(null);
$loggedInUser->setIsPrimary(false);
$this->fixtures()->persist($loggedInUser);
$this->fixtures()->flush();
$this->fixtures()->clear();
Expand All @@ -223,8 +224,8 @@ public function testDeputyUidSetWhenSingleMatchFound()

$loggedInUser = $this->fixtures()->clear()->getRepo('User')->find($this->loggedInUserId);

$this->assertEquals('700571111000', $loggedInUser->getDeputyNo());
$this->assertEquals('700571111000', $loggedInUser->getDeputyUid());
$this->assertEquals('771177117711', $loggedInUser->getDeputyNo());
$this->assertEquals('771177117711', $loggedInUser->getDeputyUid());
self::assertTrue($loggedInUser->getPreRegisterValidatedDate() instanceof \DateTime);
self::assertTrue($loggedInUser->getIsPrimary());
}
Expand Down Expand Up @@ -308,4 +309,50 @@ public function testVerifySameDeputyCannotSignUp()
'assertResponseCode' => 425,
]);
}

public function testDeputyCannotSignUpTwice()
{
$this->buildAndPersistPreRegistrationEntity('37373737', 'SINGLE', 'test', 'deputy', '771177117711');
$this->buildAndPersistPreRegistrationEntity('48484848', 'SINGLE', 'test', 'deputy', '771177117711');
$this->fixtures()->flush();
$this->fixtures()->clear();

self::$tokenDeputy = $this->loginAsDeputy();

/** @var User $loggedInUser */
$loggedInUser = $this->fixtures()->clear()->getRepo('User')->find($this->loggedInUserId);

$loggedInUser->setDeputyNo(null);
$loggedInUser->setDeputyUid(null);
$loggedInUser->setIsPrimary(false);
$this->fixtures()->persist($loggedInUser);
$this->fixtures()->flush();
$this->fixtures()->clear();

$this->assertJsonRequest('POST', '/pre-registration/verify', [
'data' => [
'case_number' => '37373737',
'lastname' => 'I should get deleted',
],
'mustSucceed' => true,
'AuthToken' => self::$tokenDeputy,
]);

$loggedInUser = $this->fixtures()->clear()->getRepo('User')->find($this->loggedInUserId);

$this->assertEquals('771177117711', $loggedInUser->getDeputyNo());
$this->assertEquals('771177117711', $loggedInUser->getDeputyUid());
self::assertTrue($loggedInUser->getPreRegisterValidatedDate() instanceof \DateTime);
self::assertTrue($loggedInUser->getIsPrimary());

$this->assertJsonRequest('POST', '/pre-registration/verify', [
'data' => [
'case_number' => '48484848',
'lastname' => 'I should get deleted',
],
'mustSucceed' => false,
'assertResponseCode' => 464,
'AuthToken' => self::$tokenDeputy,
]);
}
}
27 changes: 10 additions & 17 deletions api/app/tests/Unit/Controller/SelfRegisterControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public function userNotFoundinPreRegistration()
*/
public function throwErrorForDuplicate()
{
$preRegistration = $this->generatePreRegistration('12345678', 'Cross-Tolley', '700000019957', 'Zac', 'Tolley');
$preRegistration = $this->generatePreRegistration('12345678', 'Cross-Tolley', '700000019958', 'Zac', 'Tolley');

$this->fixtures()->persist($preRegistration);
$this->fixtures()->flush($preRegistration);
Expand Down Expand Up @@ -512,9 +512,9 @@ public function generatePreRegistration(string $caseNumber, string $clientSurnam
/**
* @test
*/
public function testDeputiesNonPrimaryAccountSetToFalse()
public function testSameDeputyCannotRegisterTwice()
{
$this->generateDeputyPrimaryAccount();
$this->generateDeputyPrimaryAccount('700000019965');
$token = $this->login('[email protected]', 'DigidepsPass1234', API_TOKEN_DEPUTY);

// create second deputy account
Expand All @@ -524,7 +524,8 @@ public function testDeputiesNonPrimaryAccountSetToFalse()
$this->fixtures()->flush($preRegistration2);

$responseArray = $this->assertJsonRequest('POST', '/selfregister', [
'mustSucceed' => true,
'mustFail' => true,
'assertResponseCode' => 464,
'AuthToken' => $token,
'data' => [
'firstname' => 'Zac',
Expand All @@ -537,12 +538,6 @@ public function testDeputiesNonPrimaryAccountSetToFalse()
],
'ClientSecret' => API_TOKEN_DEPUTY,
]);

$id = $responseArray['data']['id'];

$user = self::fixtures()->getRepo('User')->findOneBy(['id' => $id]);
$this->assertEquals('700000019965', $user->getDeputyUid());
$this->assertFalse($user->getIsPrimary());
}

/**
Expand Down Expand Up @@ -609,7 +604,7 @@ public function testNoExistingAccountsAreIdentifiedForCoDeputyWithSingleAccount(
public function testExistingAccountsAreIdentifiedForCoDeputyWithASecondAccount()
{
// first registered deputy account
$deputyPrimaryAccountUid = $this->generateDeputyPrimaryAccount();
$deputyPrimaryAccountUid = $this->generateDeputyPrimaryAccount('700000019937');

// new deputy and co-deputy pre-registration (which will be the second account for co-deputy)
$this->generateDeputyAndCoDeputyPreRegistration($deputyPrimaryAccountUid);
Expand Down Expand Up @@ -647,7 +642,8 @@ public function testExistingAccountsAreIdentifiedForCoDeputyWithASecondAccount()
$this->fixtures()->flush();

$responseArray = $this->assertJsonRequest('POST', '/selfregister/verifycodeputy', [
'mustSucceed' => true,
'mustFail' => true,
'assertResponseCode' => 464,
'AuthToken' => $token,
'data' => [
'firstname' => 'Sue',
Expand All @@ -660,9 +656,6 @@ public function testExistingAccountsAreIdentifiedForCoDeputyWithASecondAccount()
],
'ClientSecret' => API_TOKEN_DEPUTY,
]);

$existingDeputyAccounts = $responseArray['data']['existingDeputyAccounts'];
$this->assertNotEmpty($existingDeputyAccounts);
}

/**
Expand Down Expand Up @@ -749,10 +742,10 @@ private function generateDeputyAndCoDeputyPreRegistration($deputyPrimaryUid)
return $deputyPreRegistration;
}

private function generateDeputyPrimaryAccount()
private function generateDeputyPrimaryAccount(string $deputyUid)
{
$casenumber = strval(mt_rand(10000000, 99999999));
$preRegistration = $this->generatePreRegistration($casenumber, 'Smith', '700000019965', 'Sue', 'Jones');
$preRegistration = $this->generatePreRegistration($casenumber, 'Smith', $deputyUid, 'Sue', 'Jones');

$this->fixtures()->persist($preRegistration);
$this->fixtures()->flush($preRegistration);
Expand Down
36 changes: 36 additions & 0 deletions api/app/tests/Unit/Service/UserRegistrationServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,42 @@ public function testUserCannotRegisterIfOrganisationExists()
$this->userRegistrationService->selfRegisterUser($data);
}

public function testUserCannotRegisterIfTheyHaveAlreadyRegistered()
{
$data = new SelfRegisterData();
$data->setFirstname('Chris');
$data->setLastname('Haden');
$data->setEmail('[email protected]');
$data->setClientLastname('Biden');
$data->setCaseNumber('8765432T');

$clientRepo = m::mock(ClientRepository::class)
->shouldReceive('findByCaseNumber')->andReturn(null)
->getMock();

$userRepo = m::mock(UserRepository::class)
->shouldReceive('findOneByEmail')->andReturn(null)
->getMock();

$em = m::mock(EntityManager::class)
->shouldReceive('getRepository')->with('App\Entity\Client')->andReturn($clientRepo)
->shouldReceive('getRepository')->with('App\Entity\User')->andReturn($userRepo)
->getMock();

$preRegVerificationService = m::mock(PreRegistrationVerificationService::class)
->shouldReceive('isMultiDeputyCase')->andReturn(false)
->shouldReceive('validate')
->shouldReceive('getLastMatchedDeputyNumbers')->andReturn([0 => '700770077007'])
->shouldReceive('deputyHasNotSignedUpAlready')->andReturn(false)
->getMock();

self::expectException(\RuntimeException::class);
self::expectExceptionMessage('Deputy has already registered for the service');

$this->userRegistrationService = new UserRegistrationService($em, $preRegVerificationService);
$this->userRegistrationService->selfRegisterUser($data);
}

public function tearDown(): void
{
m::close();
Expand Down
4 changes: 4 additions & 0 deletions client/app/src/Controller/ClientController.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ public function addAction(Request $request, Redirector $redirector, TranslatorIn
$form->addError(new FormError($translator->trans('formErrors.deputyNotUniquelyIdentified', [], 'register')));
break;

case 464:
$form->addError(new FormError($translator->trans('formErrors.deputyAlreadyRegistered', [], 'register')));
break;

default:
$form->addError(new FormError($translator->trans('formErrors.generic', [], 'register')));
}
Expand Down
4 changes: 4 additions & 0 deletions client/app/src/Controller/CoDeputyController.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ public function verificationAction(Request $request, Redirector $redirector, Val
$form->addError(new FormError($translator->trans('formErrors.deputyAlreadyLinkedToCaseNumber', [], 'register')));
break;

case 464:
$form->addError(new FormError($translator->trans('formErrors.deputyAlreadyRegistered', [], 'register')));
break;

default:
$form->addError(new FormError($translator->trans('formErrors.generic', [], 'register')));
}
Expand Down
4 changes: 4 additions & 0 deletions client/app/src/Controller/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,10 @@ public function registerAction(Request $request)
$form->addError(new FormError($this->translator->trans('formErrors.deputyNotUniquelyIdentified', [], 'register')));
break;

case 464:
$form->addError(new FormError($this->translator->trans('formErrors.deputyAlreadyRegistered', [], 'register')));
break;

default:
$form->addError(new FormError($this->translator->trans('formErrors.generic', [], 'register')));
}
Expand Down
2 changes: 2 additions & 0 deletions client/app/translations/register.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ formErrors:
Please call 0115 934 2700 to make sure we have the correct record of your deputyship.
deputyAlreadyLinkedToCaseNumber: |
You are already registered as a deputy for this case. Please check your case number and try again. If you have any questions, call our helpline on 0115 934 2700.
deputyAlreadyRegistered: |
You have already registered as a deputy. Please log in to your account to view this case. If you have any questions, call our helpline on 0115 934 2700.

matchingErrors:
caseNumber: |
Expand Down
Loading