diff --git a/src/main/java/gov/cabinetoffice/gap/applybackend/repository/SubmissionRepository.java b/src/main/java/gov/cabinetoffice/gap/applybackend/repository/SubmissionRepository.java index 06c8d178..70be66f9 100644 --- a/src/main/java/gov/cabinetoffice/gap/applybackend/repository/SubmissionRepository.java +++ b/src/main/java/gov/cabinetoffice/gap/applybackend/repository/SubmissionRepository.java @@ -4,10 +4,11 @@ import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; +import java.util.Optional; import java.util.UUID; public interface SubmissionRepository extends JpaRepository { - List findByApplicantId(long applicantId); + Optional findByIdAndApplicantUserId(UUID id, UUID userId); } diff --git a/src/main/java/gov/cabinetoffice/gap/applybackend/service/GrantApplicantService.java b/src/main/java/gov/cabinetoffice/gap/applybackend/service/GrantApplicantService.java index 8c4aece9..9a203aa8 100644 --- a/src/main/java/gov/cabinetoffice/gap/applybackend/service/GrantApplicantService.java +++ b/src/main/java/gov/cabinetoffice/gap/applybackend/service/GrantApplicantService.java @@ -16,7 +16,7 @@ public class GrantApplicantService { private final GrantApplicantRepository grantApplicantRepository; - public GrantApplicant getApplicantById(UUID applicantId) { + public GrantApplicant getApplicantById(final UUID applicantId) { return grantApplicantRepository .findByUserId(applicantId) .orElseThrow(() -> new NotFoundException(String.format("No Grant Applicant with ID %s was found", applicantId.toString()))); diff --git a/src/main/java/gov/cabinetoffice/gap/applybackend/service/GrantApplicationService.java b/src/main/java/gov/cabinetoffice/gap/applybackend/service/GrantApplicationService.java index 34eb6c1a..fd3e0e13 100644 --- a/src/main/java/gov/cabinetoffice/gap/applybackend/service/GrantApplicationService.java +++ b/src/main/java/gov/cabinetoffice/gap/applybackend/service/GrantApplicationService.java @@ -12,13 +12,13 @@ public class GrantApplicationService { private final GrantApplicationRepository grantApplicationRepository; - public GrantApplication getGrantApplicationById(int applicationId) { + public GrantApplication getGrantApplicationById(final int applicationId) { return grantApplicationRepository .findById(applicationId) .orElseThrow(() -> new NotFoundException(String.format("No Application with ID %s was found", applicationId))); } - public boolean isGrantApplicationPublished(int applicationId) { + public boolean isGrantApplicationPublished(final int applicationId) { return getGrantApplicationById(applicationId).getApplicationStatus().equals(GrantApplicantStatus.PUBLISHED); } } diff --git a/src/main/java/gov/cabinetoffice/gap/applybackend/service/SubmissionService.java b/src/main/java/gov/cabinetoffice/gap/applybackend/service/SubmissionService.java index 88d0f6ca..a4b6a82e 100644 --- a/src/main/java/gov/cabinetoffice/gap/applybackend/service/SubmissionService.java +++ b/src/main/java/gov/cabinetoffice/gap/applybackend/service/SubmissionService.java @@ -14,7 +14,6 @@ import gov.cabinetoffice.gap.applybackend.exception.SubmissionAlreadySubmittedException; import gov.cabinetoffice.gap.applybackend.exception.SubmissionNotReadyException; import gov.cabinetoffice.gap.applybackend.model.*; -import gov.cabinetoffice.gap.applybackend.provider.UuidProvider; import gov.cabinetoffice.gap.applybackend.repository.DiligenceCheckRepository; import gov.cabinetoffice.gap.applybackend.repository.GrantBeneficiaryRepository; import gov.cabinetoffice.gap.applybackend.repository.SubmissionRepository; @@ -54,22 +53,21 @@ public class SubmissionService { private final GovNotifyClient notifyClient; private final Clock clock; - private final UuidProvider uuidProvider; private final EnvironmentProperties envProperties; - public Submission getSubmissionFromDatabaseBySubmissionId(final UUID submissionId) { + public Submission getSubmissionFromDatabaseBySubmissionId(final UUID userId, final UUID submissionId) { Submission submission = submissionRepository - .findById(submissionId) + .findByIdAndApplicantUserId(submissionId, userId) .orElseThrow(() -> new NotFoundException( String.format("No Submission with ID %s was found", submissionId))); - populateEssentialInformation(submission); + populateEssentialInformation(userId, submission); return submission; } - public SubmissionSection getSectionBySectionId(final UUID submissionId, String sectionId) { + public SubmissionSection getSectionBySectionId(final UUID userId, final UUID submissionId, String sectionId) { return submissionRepository - .findById(submissionId) + .findByIdAndApplicantUserId(submissionId, userId) .orElseThrow(() -> new NotFoundException( String.format("No Submission with ID %s was found", submissionId))) .getDefinition() @@ -80,8 +78,8 @@ public SubmissionSection getSectionBySectionId(final UUID submissionId, String s String.format("No Section with ID %s was found", sectionId))); } - public SubmissionQuestion getQuestionByQuestionId(final UUID submissionId, String questionId) { - return this.getSubmissionFromDatabaseBySubmissionId(submissionId) + public SubmissionQuestion getQuestionByQuestionId(final UUID userId, final UUID submissionId, String questionId) { + return this.getSubmissionFromDatabaseBySubmissionId(userId, submissionId) .getDefinition() .getSections() .stream() @@ -96,9 +94,9 @@ public Submission saveSubmission(final Submission submission) { return this.submissionRepository.save(submission); } - public void saveQuestionResponse(final CreateQuestionResponseDto questionResponse, final UUID submissionId, final String sectionId) { + public void saveQuestionResponse(final CreateQuestionResponseDto questionResponse, final UUID userId, final UUID submissionId, final String sectionId) { - final Submission submission = this.getSubmissionFromDatabaseBySubmissionId(submissionId); + final Submission submission = this.getSubmissionFromDatabaseBySubmissionId(userId, submissionId); final SubmissionSection submissionSection = submission.getDefinition() .getSections() .stream() @@ -141,9 +139,9 @@ public void saveQuestionResponse(final CreateQuestionResponseDto questionRespons submissionRepository.save(submission); } - public GetNavigationParamsDto getNextNavigation(final UUID submissionId, final String sectionId, final String questionId, final boolean saveAndExit) { + public GetNavigationParamsDto getNextNavigation(final UUID userId, final UUID submissionId, final String sectionId, final String questionId, final boolean saveAndExit) { - final SubmissionSection section = this.getSectionBySectionId(submissionId, sectionId); + final SubmissionSection section = this.getSectionBySectionId(userId, submissionId, sectionId); final Map nextNavigation = this.buildNextNavigationMap(section, questionId, saveAndExit); return GetNavigationParamsDto.builder() @@ -180,8 +178,8 @@ private Optional getNextQuestionIdInSection(SubmissionSection section, S return nextQuestionId; } - public boolean isSubmissionReadyToBeSubmitted(UUID submissionId) { - final Submission submission = getSubmissionFromDatabaseBySubmissionId(submissionId); + public boolean isSubmissionReadyToBeSubmitted(final UUID userId, final UUID submissionId) { + final Submission submission = getSubmissionFromDatabaseBySubmissionId(userId, submissionId); GrantApplication grantApplication = submission.getApplication(); if (!grantApplication.getApplicationStatus().equals(GrantApplicantStatus.PUBLISHED)) { return false; @@ -206,9 +204,9 @@ public boolean isSubmissionReadyToBeSubmitted(UUID submissionId) { } @Transactional - public void submit(final Submission submission, final String emailAddress) { + public void submit(final Submission submission, final UUID userId, final String emailAddress) { - if (!isSubmissionReadyToBeSubmitted(submission.getId())) { + if (!isSubmissionReadyToBeSubmitted(userId, submission.getId())) { throw new SubmissionNotReadyException(String .format("Submission %s is not ready to be submitted.", submission.getId())); } @@ -351,8 +349,8 @@ private boolean containsLocation(String[] locations, String locationToFind) { return Arrays.asList(locations).contains(locationToFind); } - public boolean hasSubmissionBeenSubmitted(UUID submissionId) { - return !this.getSubmissionFromDatabaseBySubmissionId(submissionId) + public boolean hasSubmissionBeenSubmitted(final UUID userId, final UUID submissionId) { + return !this.getSubmissionFromDatabaseBySubmissionId(userId, submissionId) .getStatus().equals(SubmissionStatus.IN_PROGRESS); } @@ -364,8 +362,9 @@ public boolean doesSubmissionExist(GrantApplicant grantApplicant, GrantApplicati } - public CreateSubmissionResponseDto createSubmissionFromApplication(GrantApplicant grantApplicant, - GrantApplication grantApplication) throws JsonProcessingException { + public CreateSubmissionResponseDto createSubmissionFromApplication(final UUID userId, + final GrantApplicant grantApplicant, + final GrantApplication grantApplication) throws JsonProcessingException { final GrantScheme grantScheme = grantApplication.getGrantScheme(); final int version = grantApplication.getVersion(); final String applicationName = grantApplication.getApplicationName(); @@ -395,17 +394,17 @@ public CreateSubmissionResponseDto createSubmissionFromApplication(GrantApplican .submissionId(submissionId) .build(); - populateEssentialInformation(submission); + populateEssentialInformation(userId, submission); return submissionResponseDto; } - private void populateEssentialInformation(Submission submission) { + private void populateEssentialInformation(final UUID userId, final Submission submission) { GrantApplicantOrganisationProfile grantApplicantOrgProfile = submission.getApplicant().getOrganisationProfile(); if (grantApplicantOrgProfile != null) { - final SubmissionSection section = getSectionBySectionId(submission.getId(), ESSENTIAL_SECTION_ID); + final SubmissionSection section = getSectionBySectionId(userId, submission.getId(), ESSENTIAL_SECTION_ID); for (SubmissionQuestion question : section.getQuestions()) { if (question.getQuestionId().equals(APPLICANT_ORG_ADDRESS)) { getMultiResponseForEssentialInfo(question, section, grantApplicantOrgProfile); @@ -429,8 +428,8 @@ private void populateEssentialInformation(Submission submission) { } } - public void deleteQuestionResponse(final UUID submissionId, final String questionId) { - final Submission submission = this.getSubmissionFromDatabaseBySubmissionId(submissionId); + public void deleteQuestionResponse(final UUID userId, final UUID submissionId, final String questionId) { + final Submission submission = this.getSubmissionFromDatabaseBySubmissionId(userId, submissionId); submission.getDefinition() .getSections() .stream() @@ -469,8 +468,11 @@ private void getMultiResponseForEssentialInfo(SubmissionQuestion question, Submi } - public SubmissionSectionStatus handleSectionReview(UUID submissionId, String sectionId, boolean isComplete) { - final Submission submission = getSubmissionFromDatabaseBySubmissionId(submissionId); + public SubmissionSectionStatus handleSectionReview(final UUID userId, + final UUID submissionId, + final String sectionId, + final boolean isComplete) { + final Submission submission = getSubmissionFromDatabaseBySubmissionId(userId, submissionId); final SubmissionSectionStatus sectionStatus = isComplete ? SubmissionSectionStatus.COMPLETED : SubmissionSectionStatus.IN_PROGRESS; submission.getDefinition() .getSections() diff --git a/src/main/java/gov/cabinetoffice/gap/applybackend/utils/SecurityContextHelper.java b/src/main/java/gov/cabinetoffice/gap/applybackend/utils/SecurityContextHelper.java new file mode 100644 index 00000000..5a28574b --- /dev/null +++ b/src/main/java/gov/cabinetoffice/gap/applybackend/utils/SecurityContextHelper.java @@ -0,0 +1,13 @@ +package gov.cabinetoffice.gap.applybackend.utils; + +import gov.cabinetoffice.gap.applybackend.dto.api.JwtPayload; +import org.springframework.security.core.context.SecurityContextHolder; + +import java.util.UUID; + +public class SecurityContextHelper { + public static UUID getUserIdFromSecurityContext() { + final JwtPayload jwtPayload = (JwtPayload) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + return UUID.fromString(jwtPayload.getSub()); + } +} diff --git a/src/main/java/gov/cabinetoffice/gap/applybackend/validation/validators/QuestionResponseValidator.java b/src/main/java/gov/cabinetoffice/gap/applybackend/validation/validators/QuestionResponseValidator.java index e5181cb3..acf0980c 100644 --- a/src/main/java/gov/cabinetoffice/gap/applybackend/validation/validators/QuestionResponseValidator.java +++ b/src/main/java/gov/cabinetoffice/gap/applybackend/validation/validators/QuestionResponseValidator.java @@ -2,6 +2,7 @@ import gov.cabinetoffice.gap.applybackend.constants.ValidationConstants; import gov.cabinetoffice.gap.applybackend.dto.api.CreateQuestionResponseDto; +import gov.cabinetoffice.gap.applybackend.dto.api.JwtPayload; import gov.cabinetoffice.gap.applybackend.enums.SubmissionQuestionResponseType; import gov.cabinetoffice.gap.applybackend.model.SubmissionQuestion; import gov.cabinetoffice.gap.applybackend.model.SubmissionQuestionValidation; @@ -11,12 +12,14 @@ import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.util.Strings; +import org.springframework.security.core.context.SecurityContextHolder; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.time.Month; import java.time.Year; import java.util.Map; +import java.util.UUID; import java.util.stream.Stream; @@ -28,6 +31,7 @@ public class QuestionResponseValidator implements ConstraintValidator> getSubmissions() { - JwtPayload jwtPayload = (JwtPayload) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - final UUID applicantId = UUID.fromString(jwtPayload.getSub()); + final UUID applicantId = getUserIdFromSecurityContext(); GrantApplicant applicant = grantApplicantService.getApplicantById((applicantId)); return ResponseEntity.ok(applicant.getSubmissions().stream() .map(this::buildSubmissionDto) @@ -53,17 +54,20 @@ public ResponseEntity> getSubmissions() { @GetMapping("/{submissionId}") public ResponseEntity getSubmission(@PathVariable final UUID submissionId) { - return ResponseEntity.ok(buildSubmissionDto(submissionService.getSubmissionFromDatabaseBySubmissionId(submissionId))); + final UUID applicantId = getUserIdFromSecurityContext(); + return ResponseEntity.ok(buildSubmissionDto(submissionService.getSubmissionFromDatabaseBySubmissionId(applicantId, submissionId))); } @GetMapping("/{submissionId}/sections/{sectionId}") public ResponseEntity getSection(@PathVariable final UUID submissionId, @PathVariable final String sectionId) { - return ResponseEntity.ok(submissionService.getSectionBySectionId(submissionId, sectionId)); + final UUID applicantId = getUserIdFromSecurityContext(); + return ResponseEntity.ok(submissionService.getSectionBySectionId(applicantId, submissionId, sectionId)); } @PostMapping("/{submissionId}/sections/{sectionId}/review") public ResponseEntity postSectionReview(@PathVariable final UUID submissionId, @PathVariable final String sectionId, final @RequestBody @Valid SubmissionReviewBodyDto body) { - final SubmissionSectionStatus sectionStatus = submissionService.handleSectionReview(submissionId, sectionId, body.getIsComplete()); + final UUID applicantId = getUserIdFromSecurityContext(); + final SubmissionSectionStatus sectionStatus = submissionService.handleSectionReview(applicantId, submissionId, sectionId, body.getIsComplete()); return ResponseEntity.ok(String.format("Section with ID %s status has been updated to %s.", sectionId, sectionStatus.toString())); } @@ -74,7 +78,9 @@ public ResponseEntity getQuestion( @PathVariable final String sectionId, @PathVariable final String questionId) { - Submission submission = submissionService.getSubmissionFromDatabaseBySubmissionId(submissionId); + final UUID applicantId = getUserIdFromSecurityContext(); + + Submission submission = submissionService.getSubmissionFromDatabaseBySubmissionId(applicantId, submissionId); SubmissionSection section = submission .getDefinition() .getSections() @@ -150,31 +156,36 @@ public ResponseEntity save(@PathVariable final UUID subm @PathVariable final String sectionId, @PathVariable final String questionId, @Valid @RequestBody CreateQuestionResponseDto questionResponse) { - submissionService.saveQuestionResponse(questionResponse, submissionId, sectionId); - return ResponseEntity.ok(submissionService.getNextNavigation(submissionId, sectionId, questionId, false)); + final UUID applicantId = getUserIdFromSecurityContext(); + submissionService.saveQuestionResponse(questionResponse, applicantId, submissionId, sectionId); + return ResponseEntity.ok(submissionService.getNextNavigation(applicantId, submissionId, sectionId, questionId, false)); } @GetMapping("/{submissionId}/ready") public ResponseEntity isSubmissionReadyToBeSubmitted(@PathVariable final UUID submissionId) { - return ResponseEntity.ok(submissionService.isSubmissionReadyToBeSubmitted(submissionId)); + final UUID applicantId = getUserIdFromSecurityContext(); + return ResponseEntity.ok(submissionService.isSubmissionReadyToBeSubmitted(applicantId, submissionId)); } @GetMapping("/{submissionId}/isSubmitted") public ResponseEntity isSubmissionSubmitted(@PathVariable final UUID submissionId) { - return ResponseEntity.ok(submissionService.hasSubmissionBeenSubmitted(submissionId)); + final UUID applicantId = getUserIdFromSecurityContext(); + return ResponseEntity.ok(submissionService.hasSubmissionBeenSubmitted(applicantId, submissionId)); } @PostMapping("/submit") public ResponseEntity submitApplication(@RequestBody SubmitApplicationDto applicationSubmission) { final JwtPayload jwtPayload = (JwtPayload) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - final Submission submission = submissionService.getSubmissionFromDatabaseBySubmissionId(applicationSubmission.getSubmissionId()); - submissionService.submit(submission, jwtPayload.getEmail()); + final UUID applicantId = getUserIdFromSecurityContext(); + final Submission submission = submissionService.getSubmissionFromDatabaseBySubmissionId(applicantId, applicationSubmission.getSubmissionId()); + submissionService.submit(submission, applicantId, jwtPayload.getEmail()); return ResponseEntity.ok("Submitted"); } @PostMapping("/createSubmission/{applicationId}") public ResponseEntity createApplication(@PathVariable final int applicationId) throws JsonProcessingException { + final UUID applicantId = getUserIdFromSecurityContext(); final boolean isGrantApplicationPublished = grantApplicationService.isGrantApplicationPublished(applicationId); if (!isGrantApplicationPublished) { logger.debug("Grant Application {} is not been published yet.", applicationId); @@ -182,9 +193,7 @@ public ResponseEntity createApplication(@PathVariab } final GrantApplication grantApplication = grantApplicationService.getGrantApplicationById(applicationId); - JwtPayload jwtPayload = (JwtPayload) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - final UUID userId = UUID.fromString(jwtPayload.getSub()); - final GrantApplicant grantApplicant = grantApplicantService.getApplicantById(userId); + final GrantApplicant grantApplicant = grantApplicantService.getApplicantById(applicantId); final boolean submissionExists = submissionService.doesSubmissionExist(grantApplicant, grantApplication); if (submissionExists) { @@ -192,7 +201,7 @@ public ResponseEntity createApplication(@PathVariab throw new SubmissionAlreadyCreatedException("SUBMISSION_EXISTS"); } - return ResponseEntity.ok(submissionService.createSubmissionFromApplication(grantApplicant, grantApplication)); + return ResponseEntity.ok(submissionService.createSubmissionFromApplication(applicantId, grantApplicant, grantApplication)); } @@ -201,10 +210,11 @@ public ResponseEntity updateAttachment(@PathVariable final UUID submissi @PathVariable final String questionId, @RequestBody final UpdateAttachmentDto updateDetails, @RequestHeader(HttpHeaders.AUTHORIZATION) final String authHeader) { + final UUID applicantId = getUserIdFromSecurityContext(); secretAuthService.authenticateSecret(authHeader); - Submission submission = submissionService.getSubmissionFromDatabaseBySubmissionId(submissionId); + Submission submission = submissionService.getSubmissionFromDatabaseBySubmissionId(applicantId, submissionId); GrantAttachment attachment = grantAttachmentService.getAttachmentBySubmissionAndQuestion(submission, questionId); attachment.setLastUpdated(Instant.now(clock)); @@ -224,8 +234,9 @@ public ResponseEntity postAttachment(@PathVariable final @PathVariable final String sectionId, @PathVariable final String questionId, @RequestBody final MultipartFile attachment) { + final UUID applicantId = getUserIdFromSecurityContext(); final GrantApplicant applicant = grantApplicantService.getApplicantFromPrincipal(); - final Submission submission = submissionService.getSubmissionFromDatabaseBySubmissionId(submissionId); + final Submission submission = submissionService.getSubmissionFromDatabaseBySubmissionId(applicantId, submissionId); final GrantApplication application = submission.getApplication(); final SubmissionQuestion question = submission.getQuestion(sectionId, questionId); @@ -267,7 +278,7 @@ public ResponseEntity postAttachment(@PathVariable final question.setResponse(attachment.getOriginalFilename()); this.submissionService.saveSubmission(submission); - return ResponseEntity.ok(submissionService.getNextNavigation(submissionId, sectionId, questionId, false)); + return ResponseEntity.ok(submissionService.getNextNavigation(applicantId, submissionId, sectionId, questionId, false)); } @DeleteMapping("/{submissionId}/sections/{sectionId}/questions/{questionId}/attachments/{attachmentId}") @@ -275,14 +286,14 @@ public ResponseEntity removeAttachment(@PathVariable fin @PathVariable final String sectionId, @PathVariable final String questionId, @PathVariable final UUID attachmentId) { - - final Submission submission = submissionService.getSubmissionFromDatabaseBySubmissionId(submissionId); + final UUID applicantId = getUserIdFromSecurityContext(); + final Submission submission = submissionService.getSubmissionFromDatabaseBySubmissionId(applicantId, submissionId); final int applicationId = submission.getApplication().getId(); final GrantAttachment attachment = grantAttachmentService.getAttachment(attachmentId); attachmentService.deleteAttachment(attachment, applicationId, submissionId, questionId); - submissionService.deleteQuestionResponse(submissionId, questionId); - submissionService.handleSectionReview(submissionId, sectionId, Boolean.FALSE); + submissionService.deleteQuestionResponse(applicantId, submissionId, questionId); + submissionService.handleSectionReview(applicantId, submissionId, sectionId, Boolean.FALSE); final GetNavigationParamsDto nextNav = GetNavigationParamsDto.builder() .responseAccepted(Boolean.TRUE) @@ -300,6 +311,7 @@ public ResponseEntity getNextNavigationForQuestion(@Path @PathVariable final String sectionId, @PathVariable final String questionId, @RequestParam(required = false, defaultValue = "false") final boolean saveAndExit) { - return ResponseEntity.ok(submissionService.getNextNavigation(submissionId, sectionId, questionId, saveAndExit)); + final UUID applicantId = getUserIdFromSecurityContext(); + return ResponseEntity.ok(submissionService.getNextNavigation(applicantId, submissionId, sectionId, questionId, saveAndExit)); } } diff --git a/src/test/java/gov/cabinetoffice/gap/applybackend/service/SubmissionServiceTest.java b/src/test/java/gov/cabinetoffice/gap/applybackend/service/SubmissionServiceTest.java index 3310209b..1472c57e 100644 --- a/src/test/java/gov/cabinetoffice/gap/applybackend/service/SubmissionServiceTest.java +++ b/src/test/java/gov/cabinetoffice/gap/applybackend/service/SubmissionServiceTest.java @@ -14,7 +14,6 @@ import gov.cabinetoffice.gap.applybackend.exception.SubmissionAlreadySubmittedException; import gov.cabinetoffice.gap.applybackend.exception.SubmissionNotReadyException; import gov.cabinetoffice.gap.applybackend.model.*; -import gov.cabinetoffice.gap.applybackend.provider.UuidProvider; import gov.cabinetoffice.gap.applybackend.repository.DiligenceCheckRepository; import gov.cabinetoffice.gap.applybackend.repository.GrantBeneficiaryRepository; import gov.cabinetoffice.gap.applybackend.repository.SubmissionRepository; @@ -50,9 +49,6 @@ class SubmissionServiceTest { @Mock private GrantBeneficiaryRepository grantBeneficiaryRepository; - @Mock - private UuidProvider uuidProvider; - @Mock private GovNotifyClient notifyClient; @@ -129,8 +125,7 @@ void setup() { .build(); serviceUnderTest = Mockito.spy(new SubmissionService(submissionRepository, diligenceCheckRepository, - grantBeneficiaryRepository, notifyClient, clock, - uuidProvider, envProperties)); + grantBeneficiaryRepository, notifyClient, clock, envProperties)); question = SubmissionQuestion.builder() .questionId(QUESTION_ID) @@ -255,11 +250,11 @@ void setup() { @Test void getSubmissionsByApplicantId_ReturnsExpectedResult() { - when(submissionRepository.findById(SUBMISSION_ID)).thenReturn(Optional.of(submission)); + when(submissionRepository.findByIdAndApplicantUserId(SUBMISSION_ID, userId)).thenReturn(Optional.of(submission)); - Submission methodResponse = serviceUnderTest.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + Submission methodResponse = serviceUnderTest.getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); - verify(submissionRepository).findById(SUBMISSION_ID); + verify(submissionRepository).findByIdAndApplicantUserId(SUBMISSION_ID, userId); assertEquals(methodResponse, submission); } @@ -314,42 +309,42 @@ void getSubmissionsByApplicantId_ReturnsExpectedResultWithEssentialInfoPopulated submission.setDefinition(definition); submission.getApplicant().setOrganisationProfile(null); - when(submissionRepository.findById(SUBMISSION_ID)).thenReturn(Optional.of(submission)); + when(submissionRepository.findByIdAndApplicantUserId(SUBMISSION_ID, userId)).thenReturn(Optional.of(submission)); - Submission methodResponse = serviceUnderTest.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + Submission methodResponse = serviceUnderTest.getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); - verify(submissionRepository).findById(SUBMISSION_ID); + verify(submissionRepository).findByIdAndApplicantUserId(SUBMISSION_ID, userId); assertEquals(methodResponse, submission); } @Test void getSubmissionsByApplicantId_SubmissionNotFound() { - when(submissionRepository.findById(SUBMISSION_ID)).thenReturn(Optional.empty()); + when(submissionRepository.findByIdAndApplicantUserId(SUBMISSION_ID, userId)).thenReturn(Optional.empty()); Exception result = assertThrows(NotFoundException.class, - () -> serviceUnderTest.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)); - verify(submissionRepository).findById(SUBMISSION_ID); + () -> serviceUnderTest.getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID)); + verify(submissionRepository).findByIdAndApplicantUserId(SUBMISSION_ID, userId); assertTrue(result.getMessage() .contains(String.format("No Submission with ID %s was found", SUBMISSION_ID))); } @Test void getSectionBySectionId_ReturnsExpectedResult() { - when(submissionRepository.findById(SUBMISSION_ID)).thenReturn(Optional.of(submission)); + when(submissionRepository.findByIdAndApplicantUserId(SUBMISSION_ID, userId)).thenReturn(Optional.of(submission)); - SubmissionSection methodResponse = serviceUnderTest.getSectionBySectionId(SUBMISSION_ID, SECTION_ID_1); + SubmissionSection methodResponse = serviceUnderTest.getSectionBySectionId(userId, SUBMISSION_ID, SECTION_ID_1); - verify(submissionRepository).findById(SUBMISSION_ID); + verify(submissionRepository).findByIdAndApplicantUserId(SUBMISSION_ID, userId); assertEquals(methodResponse, section); } @Test void getSectionBySectionId__SubmissionNotFound() { - when(submissionRepository.findById(SUBMISSION_ID)).thenReturn(Optional.empty()); + when(submissionRepository.findByIdAndApplicantUserId(SUBMISSION_ID, userId)).thenReturn(Optional.empty()); Exception result = assertThrows(NotFoundException.class, - () -> serviceUnderTest.getSectionBySectionId(SUBMISSION_ID, SECTION_ID_1)); - verify(submissionRepository).findById(SUBMISSION_ID); + () -> serviceUnderTest.getSectionBySectionId(userId, SUBMISSION_ID, SECTION_ID_1)); + verify(submissionRepository).findByIdAndApplicantUserId(SUBMISSION_ID, userId); assertTrue(result.getMessage() .contains(String.format("No Submission with ID %s was found", SUBMISSION_ID))); } @@ -357,11 +352,11 @@ void getSectionBySectionId__SubmissionNotFound() { @Test void getSectionBySectionId__SectionNotFound() { final String NO_SECTION_ID = "NONE"; - when(submissionRepository.findById(SUBMISSION_ID)).thenReturn(Optional.of(submission)); + when(submissionRepository.findByIdAndApplicantUserId(SUBMISSION_ID, userId)).thenReturn(Optional.of(submission)); Exception result = assertThrows(NotFoundException.class, - () -> serviceUnderTest.getSectionBySectionId(SUBMISSION_ID, NO_SECTION_ID)); - verify(submissionRepository).findById(SUBMISSION_ID); + () -> serviceUnderTest.getSectionBySectionId(userId, SUBMISSION_ID, NO_SECTION_ID)); + verify(submissionRepository).findByIdAndApplicantUserId(SUBMISSION_ID, userId); assertTrue(result.getMessage() .contains(String.format("No Section with ID %s was found", NO_SECTION_ID))); } @@ -400,7 +395,7 @@ void getNextNavigation_ReturnsExpectedNavigationParams(final UUID submissionId, .id(submissionId) .build(); - when(submissionRepository.findById(submissionId)) + when(submissionRepository.findByIdAndApplicantUserId(submissionId, userId)) .thenReturn(Optional.of(submission)); final GetNavigationParamsDto expected = GetNavigationParamsDto.builder() @@ -408,7 +403,7 @@ void getNextNavigation_ReturnsExpectedNavigationParams(final UUID submissionId, .nextNavigation(expectedNextNavigation) .build(); - GetNavigationParamsDto methodResponse = serviceUnderTest.getNextNavigation(submissionId, sectionId, + GetNavigationParamsDto methodResponse = serviceUnderTest.getNextNavigation(userId, submissionId, sectionId, questionId, saveAndExit); assertThat(methodResponse).isEqualTo(expected); } @@ -429,21 +424,21 @@ void getNextNavigation_ThrowsNotFoundException_IfSectionIdNotFound() { .id(submissionId) .build(); - when(submissionRepository.findById(submissionId)) + when(submissionRepository.findByIdAndApplicantUserId(submissionId, userId)) .thenReturn(Optional.of(submission)); assertThrows(NotFoundException.class, - () -> serviceUnderTest.getNextNavigation(submissionId, sectionId, questionId, false)); + () -> serviceUnderTest.getNextNavigation(userId, submissionId, sectionId, questionId, false)); } @Test void getQuestionByQuestionId_returnsExpectedQuestion() { - when(submissionRepository.findById(SUBMISSION_ID)).thenReturn(Optional.of(submission)); + when(submissionRepository.findByIdAndApplicantUserId(SUBMISSION_ID, userId)).thenReturn(Optional.of(submission)); - SubmissionQuestion methodResponse = serviceUnderTest.getQuestionByQuestionId(SUBMISSION_ID, + SubmissionQuestion methodResponse = serviceUnderTest.getQuestionByQuestionId(userId, SUBMISSION_ID, QUESTION_ID); - verify(submissionRepository).findById(SUBMISSION_ID); + verify(submissionRepository).findByIdAndApplicantUserId(SUBMISSION_ID, userId); assertEquals(methodResponse, question); } @@ -457,11 +452,11 @@ void saveQuestionResponse_SavesResponse() { .build(); doReturn(submission) - .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); final ArgumentCaptor submissionCaptor = ArgumentCaptor.forClass(Submission.class); - serviceUnderTest.saveQuestionResponse(organisationNameResponse, SUBMISSION_ID, SECTION_ID_1); + serviceUnderTest.saveQuestionResponse(organisationNameResponse, userId, SUBMISSION_ID, SECTION_ID_1); verify(submissionRepository).save(submissionCaptor.capture()); @@ -503,12 +498,12 @@ void saveEligibilityResponseToYesAltersStatus_SavesResponse() { .build(); doReturn(submission) - .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); final ArgumentCaptor submissionCaptor = ArgumentCaptor.forClass(Submission.class); - serviceUnderTest.saveQuestionResponse(questionResponse, SUBMISSION_ID, "ELIGIBILITY"); + serviceUnderTest.saveQuestionResponse(questionResponse, userId, SUBMISSION_ID, "ELIGIBILITY"); verify(submissionRepository).save(submissionCaptor.capture()); @@ -555,11 +550,11 @@ void saveEligibilityResponseToNoAltersStatus_SavesResponse() { .build(); doReturn(submission) - .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); final ArgumentCaptor submissionCaptor = ArgumentCaptor.forClass(Submission.class); - serviceUnderTest.saveQuestionResponse(questionResponse, SUBMISSION_ID, "ELIGIBILITY"); + serviceUnderTest.saveQuestionResponse(questionResponse, userId, SUBMISSION_ID, "ELIGIBILITY"); verify(submissionRepository).save(submissionCaptor.capture()); @@ -607,8 +602,8 @@ void saveQuestionResponse_ThrowsNotFoundException_IfQuestionNotFound() { .build(); doReturn(submission) - .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); - Throwable exception = assertThrows(NotFoundException.class, () -> serviceUnderTest.saveQuestionResponse(organisationNameResponse, SUBMISSION_ID, SECTION_ID_1)); + .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); + Throwable exception = assertThrows(NotFoundException.class, () -> serviceUnderTest.saveQuestionResponse(organisationNameResponse, userId, SUBMISSION_ID, SECTION_ID_1)); assertEquals("No question with ID AN-INVALID-QUESTION-ID was found", exception.getMessage()); } @@ -622,9 +617,9 @@ void saveQuestionResponse_ThrowsNotFoundException_IfSectionNotFound() { .build(); doReturn(submission) - .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); - Throwable exception = assertThrows(NotFoundException.class, () -> serviceUnderTest.saveQuestionResponse(organisationNameResponse, SUBMISSION_ID, "invalid_section_id")); + Throwable exception = assertThrows(NotFoundException.class, () -> serviceUnderTest.saveQuestionResponse(organisationNameResponse, userId, SUBMISSION_ID, "invalid_section_id")); assertEquals("No section with ID invalid_section_id was found", exception.getMessage()); } @@ -635,8 +630,8 @@ void isSubmissionReadyToBeSubmitted_returnsFalse_WhenGrantApplicationNotPublishe submission.setApplication(grantApplication); doReturn(submission) - .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); - Boolean isReadyToBeSubmitted = serviceUnderTest.isSubmissionReadyToBeSubmitted(submission.getId()); + .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); + Boolean isReadyToBeSubmitted = serviceUnderTest.isSubmissionReadyToBeSubmitted(userId, submission.getId()); assertThat(isReadyToBeSubmitted).isFalse(); } @@ -651,8 +646,8 @@ void isSubmissionReadyToBeSubmitted_returnTrueWhenAllMandatoryQuestionsHaveBeenA submission.setApplication(grantApplication); doReturn(submission) - .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); - Boolean isReadyToBeSubmitted = serviceUnderTest.isSubmissionReadyToBeSubmitted(submission.getId()); + .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); + Boolean isReadyToBeSubmitted = serviceUnderTest.isSubmissionReadyToBeSubmitted(userId, submission.getId()); assertThat(isReadyToBeSubmitted).isTrue(); } @@ -669,8 +664,8 @@ void isSubmissionReadyToBeSubmitted_returnTrueWhenAllMandatoryQuestionsHaveBeenA submission.setApplication(grantApplication); doReturn(submission) - .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); - Boolean isReadyToBeSubmitted = serviceUnderTest.isSubmissionReadyToBeSubmitted(submission.getId()); + .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); + Boolean isReadyToBeSubmitted = serviceUnderTest.isSubmissionReadyToBeSubmitted(userId, submission.getId()); assertThat(isReadyToBeSubmitted).isTrue(); } @@ -684,16 +679,16 @@ void isSubmissionReadyToBeSubmitted_returnFalseWhenAllMandatoryQuestionsHaveNotB submission.setApplication(grantApplication); doReturn(submission) - .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); - Boolean isReadyToBeSubmitted = serviceUnderTest.isSubmissionReadyToBeSubmitted(submission.getId()); + .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); + Boolean isReadyToBeSubmitted = serviceUnderTest.isSubmissionReadyToBeSubmitted(userId, submission.getId()); assertThat(isReadyToBeSubmitted).isFalse(); } @Test void submit_ThrowsSubmissionNotReadyException_IfSubmissionCannotBeSubmitted() { final String emailAddress = "test@email.com"; - doReturn(false).when(serviceUnderTest).isSubmissionReadyToBeSubmitted(SUBMISSION_ID); - assertThrows(SubmissionNotReadyException.class, () -> serviceUnderTest.submit(submission, emailAddress)); + doReturn(false).when(serviceUnderTest).isSubmissionReadyToBeSubmitted(userId, SUBMISSION_ID); + assertThrows(SubmissionNotReadyException.class, () -> serviceUnderTest.submit(submission, userId, emailAddress)); } @Test @@ -704,10 +699,10 @@ void submit_ThrowsSubmissionAlreadySubmittedException_IfSubmissionAlreadySubmitt .id(SUBMISSION_ID) .build(); - doReturn(true).when(serviceUnderTest).isSubmissionReadyToBeSubmitted(SUBMISSION_ID); + doReturn(true).when(serviceUnderTest).isSubmissionReadyToBeSubmitted(userId, SUBMISSION_ID); assertThrows(SubmissionAlreadySubmittedException.class, - () -> serviceUnderTest.submit(alreadySubmittedSubmission, emailAddress)); + () -> serviceUnderTest.submit(alreadySubmittedSubmission, userId, emailAddress)); } @Test @@ -715,9 +710,9 @@ void submit_SubmitsTheApplicationForm() { final String emailAddress = "test@email.com"; final ArgumentCaptor submissionCaptor = ArgumentCaptor.forClass(Submission.class); - doReturn(true).when(serviceUnderTest).isSubmissionReadyToBeSubmitted(SUBMISSION_ID); + doReturn(true).when(serviceUnderTest).isSubmissionReadyToBeSubmitted(userId, SUBMISSION_ID); - serviceUnderTest.submit(submission, emailAddress); + serviceUnderTest.submit(submission, userId, emailAddress); verify(notifyClient).sendConfirmationEmail(emailAddress, submission); verify(submissionRepository).save(submissionCaptor.capture()); @@ -739,9 +734,9 @@ void submit_CreatesDiligenceCheck() { final ArgumentCaptor diligenceCheckCaptor = ArgumentCaptor .forClass(DiligenceCheck.class); - doReturn(true).when(serviceUnderTest).isSubmissionReadyToBeSubmitted(SUBMISSION_ID); + doReturn(true).when(serviceUnderTest).isSubmissionReadyToBeSubmitted(userId, SUBMISSION_ID); - serviceUnderTest.submit(submission, emailAddress); + serviceUnderTest.submit(submission, userId, emailAddress); verify(diligenceCheckRepository).save(diligenceCheckCaptor.capture()); final DiligenceCheck capturedCheck = diligenceCheckCaptor.getValue(); @@ -769,10 +764,10 @@ void submit_ThrowsIllegalArgumentException_IfSectionNotPresentInSubmission() { .id(SUBMISSION_ID) .build(); - doReturn(true).when(serviceUnderTest).isSubmissionReadyToBeSubmitted(SUBMISSION_ID); + doReturn(true).when(serviceUnderTest).isSubmissionReadyToBeSubmitted(userId, SUBMISSION_ID); assertThrows(IllegalArgumentException.class, - () -> serviceUnderTest.submit(submissionWithoutEssentialSection, emailAddress)); + () -> serviceUnderTest.submit(submissionWithoutEssentialSection, userId, emailAddress)); } @ParameterizedTest @@ -792,10 +787,10 @@ void submit_ThrowsIllegalArgumentException_IfQuestionNotPresentInSection(List serviceUnderTest.submit(submissionWithoutEssentialSection, emailAddress)); + () -> serviceUnderTest.submit(submissionWithoutEssentialSection, userId, emailAddress)); } @Test @@ -805,9 +800,9 @@ void submit_CreatesGrantBeneficiary() { final ArgumentCaptor grantBeneficiaryCaptor = ArgumentCaptor .forClass(GrantBeneficiary.class); - doReturn(true).when(serviceUnderTest).isSubmissionReadyToBeSubmitted(SUBMISSION_ID); + doReturn(true).when(serviceUnderTest).isSubmissionReadyToBeSubmitted(userId, SUBMISSION_ID); - serviceUnderTest.submit(submission, emailAddress); + serviceUnderTest.submit(submission, userId, emailAddress); verify(grantBeneficiaryRepository).save(grantBeneficiaryCaptor.capture()); @@ -855,7 +850,7 @@ void createSubmissionFromApplication__returnCreateSubmissionResponseDto() throws .build(); when(submissionRepository.save(submission)).thenReturn(submission); - CreateSubmissionResponseDto response = serviceUnderTest.createSubmissionFromApplication(grantApplicant, + CreateSubmissionResponseDto response = serviceUnderTest.createSubmissionFromApplication(userId, grantApplicant, grantApplication); CreateSubmissionResponseDto expected = CreateSubmissionResponseDto.builder() .submissionCreated(true) @@ -885,18 +880,18 @@ void doesSubmissionExist_ReturnsFalse_IfSubmissionDoesNotExists() { @Test void handleSectionReview_returnSectionStatusInProgress() { doReturn(submission) - .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); when(submissionRepository.save(submission)).thenReturn(submission); - final SubmissionSectionStatus response = serviceUnderTest.handleSectionReview(SUBMISSION_ID, SECTION_ID_1, false); + final SubmissionSectionStatus response = serviceUnderTest.handleSectionReview(userId, SUBMISSION_ID, SECTION_ID_1, false); assertEquals(SubmissionSectionStatus.IN_PROGRESS, response); } @Test void handleSectionReview_returnSectionStatusCompleted() { doReturn(submission) - .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + .when(serviceUnderTest).getSubmissionFromDatabaseBySubmissionId(userId, SUBMISSION_ID); when(submissionRepository.save(submission)).thenReturn(submission); - final SubmissionSectionStatus response = serviceUnderTest.handleSectionReview(SUBMISSION_ID, SECTION_ID_1, true); + final SubmissionSectionStatus response = serviceUnderTest.handleSectionReview(userId, SUBMISSION_ID, SECTION_ID_1, true); assertEquals(SubmissionSectionStatus.COMPLETED, response); } } \ No newline at end of file diff --git a/src/test/java/gov/cabinetoffice/gap/applybackend/validation/annotations/QuestionResponseValidatorTest.java b/src/test/java/gov/cabinetoffice/gap/applybackend/validation/annotations/QuestionResponseValidatorTest.java index 1aa94dca..c47da988 100644 --- a/src/test/java/gov/cabinetoffice/gap/applybackend/validation/annotations/QuestionResponseValidatorTest.java +++ b/src/test/java/gov/cabinetoffice/gap/applybackend/validation/annotations/QuestionResponseValidatorTest.java @@ -1,6 +1,7 @@ package gov.cabinetoffice.gap.applybackend.validation.annotations; import gov.cabinetoffice.gap.applybackend.dto.api.CreateQuestionResponseDto; +import gov.cabinetoffice.gap.applybackend.dto.api.JwtPayload; import gov.cabinetoffice.gap.applybackend.exception.NotFoundException; import gov.cabinetoffice.gap.applybackend.model.SubmissionQuestion; import gov.cabinetoffice.gap.applybackend.model.SubmissionQuestionValidation; @@ -18,6 +19,9 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; import javax.validation.ConstraintValidatorContext; import java.util.List; @@ -31,9 +35,14 @@ @ExtendWith(MockitoExtension.class) class QuestionResponseValidatorTest { + @Mock + private Authentication authentication; @Mock private SubmissionService submissionService; + @Mock + private SecurityContext securityContext; + private ConstraintValidatorContext validatorContext; private ConstraintValidatorContext.ConstraintViolationBuilder builder; private ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext nodeBuilder; @@ -42,6 +51,7 @@ class QuestionResponseValidatorTest { static final String questionId = "1"; static final UUID submissionId = UUID.fromString("3a6cfe2d-bf58-440d-9e07-3579c7dcf205"); + private final UUID USER_ID = UUID.randomUUID(); @BeforeEach void setup() { @@ -50,6 +60,11 @@ void setup() { validatorContext = mock(ConstraintValidatorContext.class); validatorUnderTest = new QuestionResponseValidator(submissionService); + + when(securityContext.getAuthentication()).thenReturn(authentication); + SecurityContextHolder.setContext(securityContext); + JwtPayload jwtPayload = JwtPayload.builder().sub(String.valueOf(USER_ID)).build(); + when(SecurityContextHolder.getContext().getAuthentication().getPrincipal()).thenReturn(jwtPayload); } private static Stream provideTestData() { @@ -159,11 +174,11 @@ void validate_returnsFalseWhenInvalidResponseProvided(CreateQuestionResponseDto .thenReturn(nodeBuilder); doReturn(question) - .when(submissionService).getQuestionByQuestionId(submissionId, questionId); + .when(submissionService).getQuestionByQuestionId(USER_ID, submissionId, questionId); boolean isValid = validatorUnderTest.isValid(response, validatorContext); - verify(submissionService).getQuestionByQuestionId(submissionId, questionId); + verify(submissionService).getQuestionByQuestionId(USER_ID, submissionId, questionId); verify(validatorContext).buildConstraintViolationWithTemplate(message); assertThat(isValid).isFalse(); @@ -207,7 +222,7 @@ void validate_returnsCorrectMessageForMandatoryQuestionTypes(SubmissionQuestionR .thenReturn(nodeBuilder); doReturn(question) - .when(submissionService).getQuestionByQuestionId(submissionId, questionId); + .when(submissionService).getQuestionByQuestionId(USER_ID, submissionId, questionId); validatorUnderTest.isValid(response, validatorContext); @@ -237,17 +252,16 @@ void validate_returnsTrueIfValidResponseProvided() { .build(); doReturn(shortAnswerQuestion) - .when(submissionService).getQuestionByQuestionId(submissionId, questionId); + .when(submissionService).getQuestionByQuestionId(USER_ID, submissionId, questionId); boolean isValid = validatorUnderTest.isValid(response, validatorContext); - verify(submissionService).getQuestionByQuestionId(submissionId, questionId); + verify(submissionService).getQuestionByQuestionId(USER_ID, submissionId, questionId); assertThat(isValid).isTrue(); } @Test void throwsIllegalArgumentException_IfQuestionIdIsNull() { - final CreateQuestionResponseDto response = CreateQuestionResponseDto.builder() .submissionId(submissionId) .response("a valid question response") @@ -276,7 +290,7 @@ void ThrowsNotFoundException_IfQuestionNotInDatabase() { .response("a valid question response") .build(); - when(submissionService.getQuestionByQuestionId(submissionId, questionId)) + when(submissionService.getQuestionByQuestionId(USER_ID, submissionId, questionId)) .thenThrow(new NotFoundException("")); assertThrows(NotFoundException.class, () -> validatorUnderTest.isValid(response, validatorContext)); @@ -307,7 +321,7 @@ void validate_ReturnsTrueIfDateIsValid() { .build(); doReturn(question) - .when(submissionService).getQuestionByQuestionId(submissionId, questionId); + .when(submissionService).getQuestionByQuestionId(USER_ID, submissionId, questionId); boolean isValid = validatorUnderTest.isValid(response, validatorContext); @@ -358,7 +372,7 @@ void validate_returnsFalse_WithExpectedError(String[] dateParts, String message) .build(); doReturn(question) - .when(submissionService).getQuestionByQuestionId(submissionId, questionId); + .when(submissionService).getQuestionByQuestionId(USER_ID, submissionId, questionId); when(validatorContext.buildConstraintViolationWithTemplate(Mockito.anyString())) .thenReturn(builder); @@ -392,7 +406,7 @@ void validate_ReturnsTrueIfAddressIsValid() { .build(); doReturn(question) - .when(submissionService).getQuestionByQuestionId(submissionId, questionId); + .when(submissionService).getQuestionByQuestionId(USER_ID, submissionId, questionId); boolean isValid = validatorUnderTest.isValid(response, validatorContext); @@ -430,7 +444,7 @@ void validate_ThrowsIllegalArgumentException_IfAddressArraySizeIsNot5(String[] a .build(); doReturn(question) - .when(submissionService).getQuestionByQuestionId(submissionId, questionId); + .when(submissionService).getQuestionByQuestionId(USER_ID, submissionId, questionId); assertThrows(IllegalArgumentException.class, () -> validatorUnderTest.isValid(response, validatorContext)); } @@ -473,7 +487,7 @@ void validate_ReturnsFalse_IfAddressIsInvalid(String[] addressResponse, List response = controllerUnderTest.getSubmission(SUBMISSION_ID); - verify(submissionService).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + verify(submissionService).getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID); assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals(response.getBody(), getSubmissionDto1); } @Test void getSection_ReturnsExpectedResponse() { - when(submissionService.getSectionBySectionId(SUBMISSION_ID, SECTION_ID_1)) + when(submissionService.getSectionBySectionId(APPLICANT_USER_ID, SUBMISSION_ID, SECTION_ID_1)) .thenReturn(section1); ResponseEntity response = controllerUnderTest.getSection(SUBMISSION_ID, SECTION_ID_1); - verify(submissionService).getSectionBySectionId(SUBMISSION_ID, SECTION_ID_1); + verify(submissionService).getSectionBySectionId(APPLICANT_USER_ID, SUBMISSION_ID, SECTION_ID_1); assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals(response.getBody(), section1); } @Test void getQuestion_ReturnsExpectedResponseNoNextNavigation() { - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(submission); ResponseEntity response = controllerUnderTest.getQuestion(SUBMISSION_ID, SECTION_ID_1, QUESTION_ID_1); - verify(submissionService).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + verify(submissionService).getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID); assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals(getQuestionDto1, response.getBody()); } @Test void getQuestion_ReturnsExpectedResponseNextAndPreviousNavigation() { - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(submission); ResponseEntity response = controllerUnderTest.getQuestion(SUBMISSION_ID, SECTION_ID_1, QUESTION_ID_2); - verify(submissionService).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + verify(submissionService).getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID); assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals(getQuestionDto2, response.getBody()); } @Test void getQuestion_ReturnsExpectedResponseNoPreviousNavigation() { - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(submission); ResponseEntity response = controllerUnderTest.getQuestion(SUBMISSION_ID, SECTION_ID_1, QUESTION_ID_3); - verify(submissionService).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + verify(submissionService).getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID); assertEquals(HttpStatus.OK, response.getStatusCode()); assertEquals(getQuestionDto3, response.getBody()); } @@ -344,22 +341,22 @@ void getQuestion_ReturnsExpectedResponseNoPreviousNavigation() { @Test void getQuestion_ThrowWhenSectionNotFound() { String sectionId = "NONE"; - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(submission); Exception result = assertThrows(NotFoundException.class, () -> controllerUnderTest.getQuestion(SUBMISSION_ID, sectionId, QUESTION_ID_1)); - verify(submissionService).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + verify(submissionService).getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID); assertTrue(result.getMessage().contains(String.format("No Section with ID %s was found", sectionId))); } @Test void getQuestion_ThrowWhenQuestionNotFound() { String questionId = "NONE"; - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(submission); Exception result = assertThrows(NotFoundException.class, () -> controllerUnderTest.getQuestion(SUBMISSION_ID, SECTION_ID_1, questionId)); - verify(submissionService).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + verify(submissionService).getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID); assertTrue(result.getMessage().contains(String.format("No question with ID %s was found", questionId))); } @@ -373,18 +370,18 @@ void save_savesQuestionResponseAndReturnsExpectedNextNav() { .build(); doReturn(nextNav) - .when(submissionService).getNextNavigation(SUBMISSION_ID, SECTION_ID_1, QUESTION_ID_1, false); + .when(submissionService).getNextNavigation(APPLICANT_USER_ID, SUBMISSION_ID, SECTION_ID_1, QUESTION_ID_1, false); ResponseEntity methodResponse = controllerUnderTest.save(SUBMISSION_ID, SECTION_ID_1, QUESTION_ID_1, questionResponse); - verify(submissionService).saveQuestionResponse(questionResponse, SUBMISSION_ID, SECTION_ID_1); + verify(submissionService).saveQuestionResponse(questionResponse, APPLICANT_USER_ID, SUBMISSION_ID, SECTION_ID_1); assertThat(methodResponse.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(methodResponse.getBody()).isEqualTo(nextNav); } @Test void isSubmissionReadyToBeSubmitted_ReturnsExpectedResponse_ReturnTrue() { - when(submissionService.isSubmissionReadyToBeSubmitted(SUBMISSION_ID)) + when(submissionService.isSubmissionReadyToBeSubmitted(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(true); ResponseEntity response = controllerUnderTest.isSubmissionReadyToBeSubmitted(SUBMISSION_ID); @@ -396,7 +393,7 @@ void isSubmissionReadyToBeSubmitted_ReturnsExpectedResponse_ReturnTrue() { @Test void isSubmissionReadyToBeSubmitted_ReturnsExpectedResponse_ReturnFalse() { - when(submissionService.isSubmissionReadyToBeSubmitted(SUBMISSION_ID)) + when(submissionService.isSubmissionReadyToBeSubmitted(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(false); ResponseEntity response = controllerUnderTest.isSubmissionReadyToBeSubmitted(SUBMISSION_ID); @@ -413,16 +410,16 @@ void submitApplication_isSuccessfulAndReturnsExpectedResponse() { final SubmitApplicationDto submitApplication = SubmitApplicationDto.builder() .submissionId(SUBMISSION_ID) .build(); - final JwtPayload jwtPayload = JwtPayload.builder().email(emailAddress).build(); + final JwtPayload jwtPayload = JwtPayload.builder().sub(String.valueOf(APPLICANT_USER_ID)).email(emailAddress).build(); when(SecurityContextHolder.getContext().getAuthentication().getPrincipal()).thenReturn(jwtPayload); - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(submission); ResponseEntity response = controllerUnderTest.submitApplication(submitApplication); - verify(submissionService).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); - verify(submissionService).submit(submission, emailAddress); + verify(submissionService).getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID); + verify(submissionService).submit(submission, APPLICANT_USER_ID, emailAddress); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(response.getBody()).isEqualTo("Submitted"); @@ -435,11 +432,11 @@ void submitApplication_ThrowsNotFoundException_IfSubmissionNotFound() { .submissionId(SUBMISSION_ID) .build(); - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenThrow(new NotFoundException("")); assertThrows(NotFoundException.class, () -> controllerUnderTest.submitApplication(submitApplication)); - verify(submissionService).getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID); + verify(submissionService).getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID); } @Test @@ -471,7 +468,6 @@ void createApplication__submissionAlreadyExists_ThrowSubmissionAlreadyCreatedExc @Test void createApplication() throws JsonProcessingException { final UUID submissionId = UUID.fromString("1c2eabf0-b33c-433a-b00f-e73d8efca929"); - final SubmissionDefinition definition = new SubmissionDefinition(); final ApplicationDefinition applicationDefinition = new ApplicationDefinition(); final GrantScheme grantScheme = new GrantScheme(); @@ -495,7 +491,7 @@ void createApplication() throws JsonProcessingException { when(grantApplicationService.isGrantApplicationPublished(1)).thenReturn(true); when(grantApplicationService.getGrantApplicationById(1)).thenReturn(grantApplication); when(grantApplicantService.getApplicantById(applicantId)).thenReturn(grantApplicant); - when(submissionService.createSubmissionFromApplication(grantApplicant, grantApplication)).thenReturn(createSubmissionResponseDto); + when(submissionService.createSubmissionFromApplication(APPLICANT_USER_ID, grantApplicant, grantApplication)).thenReturn(createSubmissionResponseDto); ResponseEntity response = controllerUnderTest.createApplication(1); @@ -507,7 +503,7 @@ void createApplication() throws JsonProcessingException { @Test void postSectionReview_completedSectionStatus() { final SubmissionReviewBodyDto submissionReviewBodyDto = SubmissionReviewBodyDto.builder().isComplete(true).build(); - when(submissionService.handleSectionReview(SUBMISSION_ID, SECTION_ID_1, submissionReviewBodyDto.getIsComplete())).thenReturn(SubmissionSectionStatus.COMPLETED); + when(submissionService.handleSectionReview(APPLICANT_USER_ID, SUBMISSION_ID, SECTION_ID_1, submissionReviewBodyDto.getIsComplete())).thenReturn(SubmissionSectionStatus.COMPLETED); final ResponseEntity result = controllerUnderTest.postSectionReview(SUBMISSION_ID, SECTION_ID_1, submissionReviewBodyDto); assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals(result.getBody(), String.format("Section with ID %s status has been updated to %s.", SECTION_ID_1, SubmissionSectionStatus.COMPLETED)); @@ -516,7 +512,7 @@ void postSectionReview_completedSectionStatus() { @Test void postSectionReview_inProgressSectionStatus() { final SubmissionReviewBodyDto submissionReviewBodyDto = SubmissionReviewBodyDto.builder().isComplete(false).build(); - when(submissionService.handleSectionReview(SUBMISSION_ID, SECTION_ID_1, submissionReviewBodyDto.getIsComplete())).thenReturn(SubmissionSectionStatus.IN_PROGRESS); + when(submissionService.handleSectionReview(APPLICANT_USER_ID, SUBMISSION_ID, SECTION_ID_1, submissionReviewBodyDto.getIsComplete())).thenReturn(SubmissionSectionStatus.IN_PROGRESS); final ResponseEntity result = controllerUnderTest.postSectionReview(SUBMISSION_ID, SECTION_ID_1, submissionReviewBodyDto); assertEquals(HttpStatus.OK, result.getStatusCode()); assertEquals(result.getBody(), String.format("Section with ID %s status has been updated to %s.", SECTION_ID_1, SubmissionSectionStatus.IN_PROGRESS)); @@ -529,7 +525,7 @@ void postSectionReview_bodyIsNull() { } @Test void isSubmissionSubmitted_returnsExpectedResult() { - when(submissionService.hasSubmissionBeenSubmitted(SUBMISSION_ID)) + when(submissionService.hasSubmissionBeenSubmitted(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(true); final ResponseEntity methodResponse = controllerUnderTest.isSubmissionSubmitted(SUBMISSION_ID); @@ -563,7 +559,7 @@ void updateAttachment_UpdatesExpectedAttachment(UpdateAttachmentDto update, Gran final GrantAttachment attachment = GrantAttachment.builder().build(); - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(submission); when(grantAttachmentService.getAttachmentBySubmissionAndQuestion(submission, QUESTION_ID_1)) @@ -620,10 +616,10 @@ void postAttachment_SavesTheDocumentAndCreatesADatabaseEntry() { when(grantApplicantService.getApplicantFromPrincipal()) .thenReturn(grantApplicant); - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(submission); - when(submissionService.getNextNavigation(SUBMISSION_ID, SECTION_ID_2, questionId, false)) + when(submissionService.getNextNavigation(APPLICANT_USER_ID, SUBMISSION_ID, SECTION_ID_2, questionId, false)) .thenReturn(expectedNavigation); final ArgumentCaptor attachmentCaptor = ArgumentCaptor.forClass(GrantAttachment.class); @@ -658,7 +654,7 @@ void postAttachment_ThrowsAttachmentException_IfAttachmentIsNull() { when(grantApplicantService.getApplicantFromPrincipal()) .thenReturn(grantApplicant); - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(submission); final AttachmentException ex = assertThrows(AttachmentException.class, () -> controllerUnderTest.postAttachment(SUBMISSION_ID, SECTION_ID_2, questionId, null)); @@ -693,7 +689,7 @@ void postAttachment_ThrowsAttachmentException_IfAttachmentIsEmpty() { when(grantApplicantService.getApplicantFromPrincipal()) .thenReturn(grantApplicant); - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(submission); final AttachmentException ex = assertThrows(AttachmentException.class, () -> controllerUnderTest.postAttachment(SUBMISSION_ID, SECTION_ID_2, questionId, file)); @@ -729,7 +725,7 @@ void postAttachment_ThrowsAttachmentException_IfQuestionAlreadyHasAnAttachment() when(grantApplicantService.getApplicantFromPrincipal()) .thenReturn(grantApplicant); - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(submission); final AttachmentException ex = assertThrows(AttachmentException.class, () -> controllerUnderTest.postAttachment(SUBMISSION_ID, SECTION_ID_2, questionId, file)); @@ -754,7 +750,7 @@ void removeAttachment_RemovesFileFromS3_AndDeletesDatabaseEntry() { )) .build(); - when(submissionService.getSubmissionFromDatabaseBySubmissionId(SUBMISSION_ID)) + when(submissionService.getSubmissionFromDatabaseBySubmissionId(APPLICANT_USER_ID, SUBMISSION_ID)) .thenReturn(submission); when(grantAttachmentService.getAttachment(attachmentId)) @@ -766,8 +762,8 @@ void removeAttachment_RemovesFileFromS3_AndDeletesDatabaseEntry() { assertThat(methodResponse.getBody()).isEqualTo(expectedNav); verify(attachmentService).deleteAttachment(attachment, applicationId, SUBMISSION_ID, QUESTION_ID_1); - verify(submissionService).deleteQuestionResponse(SUBMISSION_ID, QUESTION_ID_1); - verify(submissionService).handleSectionReview(SUBMISSION_ID, SECTION_ID_1, Boolean.FALSE); + verify(submissionService).deleteQuestionResponse(APPLICANT_USER_ID, SUBMISSION_ID, QUESTION_ID_1); + verify(submissionService).handleSectionReview(APPLICANT_USER_ID, SUBMISSION_ID, SECTION_ID_1, Boolean.FALSE); } @Test @@ -781,7 +777,7 @@ void getNextNavigationForQuestion_ReturnsExpectedResult() { )) .build(); - when(submissionService.getNextNavigation(SUBMISSION_ID, SECTION_ID_1, QUESTION_ID_1, false)) + when(submissionService.getNextNavigation(APPLICANT_USER_ID, SUBMISSION_ID, SECTION_ID_1, QUESTION_ID_1, false)) .thenReturn(expectedNav); final ResponseEntity methodResponse = controllerUnderTest.getNextNavigationForQuestion(SUBMISSION_ID, SECTION_ID_1, QUESTION_ID_1, false);