diff --git a/app/configuration/ApplicationConfig.scala b/app/configuration/ApplicationConfig.scala index 73f183d90..4319ee7c4 100644 --- a/app/configuration/ApplicationConfig.scala +++ b/app/configuration/ApplicationConfig.scala @@ -32,6 +32,4 @@ class ApplicationConfig @Inject() (configuration: Configuration) { val draftMetadataFileName: String = configuration.get[String]("draftMetadata.fileName") val notificationSnsTopicArn: String = get("notificationSnsTopicArn") - - val fileChecksTotalTimoutInSeconds: Int = configuration.get[Int]("fileChecksTotalTimoutInSeconds") } diff --git a/app/controllers/FileChecksController.scala b/app/controllers/FileChecksController.scala index bfccc4515..d3fbb1d62 100644 --- a/app/controllers/FileChecksController.scala +++ b/app/controllers/FileChecksController.scala @@ -7,14 +7,14 @@ import graphql.codegen.types.ConsignmentStatusInput import io.circe.syntax._ import org.pac4j.play.scala.SecurityComponents import play.api.i18n.I18nSupport -import play.api.mvc._ -import services.Statuses._ -import services._ +import play.api.mvc.{Action, AnyContent, Request, RequestHeader} +import services.Statuses.{CompletedValue, CompletedWithIssuesValue, UploadType} +import services.{BackendChecksService, ConsignmentService, ConsignmentStatusService} import viewsapi.Caching.preventCaching import java.util.UUID import javax.inject.{Inject, Singleton} -import scala.concurrent.{ExecutionContext, Future, blocking} +import scala.concurrent.{ExecutionContext, Future} @Singleton class FileChecksController @Inject() ( @@ -24,16 +24,14 @@ class FileChecksController @Inject() ( val consignmentService: ConsignmentService, val applicationConfig: ApplicationConfig, val backendChecksService: BackendChecksService, - val consignmentStatusService: ConsignmentStatusService, - val confirmTransferService: ConfirmTransferService, - val consignmentExportService: ConsignmentExportService + val consignmentStatusService: ConsignmentStatusService )(implicit val ec: ExecutionContext) extends TokenSecurity with I18nSupport { private def getFileChecksProgress(request: Request[AnyContent], consignmentId: UUID)(implicit requestHeader: RequestHeader): Future[FileChecksProgress] = { consignmentService - .fileCheckProgress(consignmentId, request.token.bearerAccessToken) + .getConsignmentFileChecks(consignmentId, request.token.bearerAccessToken) .map { fileCheckProgress => FileChecksProgress( fileCheckProgress.totalFiles, @@ -95,24 +93,6 @@ class FileChecksController @Inject() ( } yield result } - def judgmentCompleteTransfer(consignmentId: UUID): Action[AnyContent] = judgmentTypeAction(consignmentId) { implicit request: Request[AnyContent] => - val token = request.token.bearerAccessToken - for { - reference <- consignmentService.getConsignmentRef(consignmentId, token) - result <- - ( - for { - _ <- waitForFileChecksToBeCompleted(consignmentId) - result <- JudgmentCompleteTransfer(consignmentId) - } yield result - ).recover { case _: Exception => - Ok(views.html.uploadInProgress(consignmentId, reference, "Uploading your records", request.token.name, isJudgmentUser = true)).uncache() - } - } yield { - result - } - } - private def handleSuccessfulUpload(consignmentId: UUID, reference: String, isJudgmentUser: Boolean)(implicit request: Request[AnyContent]) = { val token = request.token.bearerAccessToken (for { @@ -145,66 +125,10 @@ class FileChecksController @Inject() ( .uncache() } } - }).recover { case _: Exception => + }).recover { case exception: Exception => Ok(views.html.uploadInProgress(consignmentId, reference, "Uploading your records", request.token.name, isJudgmentUser)).uncache() } } - - private def JudgmentCompleteTransfer(consignmentId: UUID)(implicit request: Request[AnyContent]): Future[Result] = { - val pageTitle = "Results of checks" - for { - consignmentStatuses <- consignmentStatusService.getConsignmentStatuses(consignmentId, request.token.bearerAccessToken) - reference <- consignmentService.getConsignmentRef(consignmentId, request.token.bearerAccessToken) - exportStatus = consignmentStatusService.getStatusValues(consignmentStatuses, ExportType).values.headOption.flatten - result <- exportStatus match { - case Some(InProgressValue.value) | Some(CompletedValue.value) | Some(FailedValue.value) => - Future(Ok(views.html.transferAlreadyCompleted(consignmentId, reference, request.token.name, isJudgmentUser = true)).uncache()) - case None => - for { - fileCheck <- consignmentService.fileCheckProgress(consignmentId, request.token.bearerAccessToken) - result <- - if (fileCheck.allChecksSucceeded) { - val token: BearerAccessToken = request.token.bearerAccessToken - val legalCustodyTransferConfirmation = FinalTransferConfirmationData(transferLegalCustody = true) - for { - _ <- confirmTransferService.addFinalTransferConfirmation(consignmentId, token, legalCustodyTransferConfirmation) - _ <- consignmentExportService.updateTransferInitiated(consignmentId, request.token.bearerAccessToken) - _ <- consignmentExportService.triggerExport(consignmentId, request.token.bearerAccessToken.toString) - res <- Future(Redirect(routes.TransferCompleteController.judgmentTransferComplete(consignmentId)).uncache()) - } yield res - } else { - Future(Ok(views.html.fileChecksResultsFailed(request.token.name, pageTitle, reference, isJudgmentUser = true)).uncache()) - } - } yield result - case _ => - throw new IllegalStateException(s"Unexpected Export status: $exportStatus for consignment $consignmentId") - } - } yield result - } - - private def waitForFileChecksToBeCompleted(consignmentId: UUID)(implicit request: Request[AnyContent]): Future[Unit] = { - val totalSleepTime = applicationConfig.fileChecksTotalTimoutInSeconds * 1000 // Total sleep time in milliseconds - val interval = 5 * 1000 // Interval time in milliseconds (5 seconds) - val intervals = totalSleepTime / interval - - def checkStatus(remainingIntervals: Int): Future[Unit] = { - if (remainingIntervals <= 0) { - Future.unit - } else { - getFileChecksProgress(request, consignmentId).flatMap { progress => - if (progress.isComplete) { - Future.unit - } else { - Future { - blocking(Thread.sleep(interval)) - }.flatMap(_ => checkStatus(remainingIntervals - 1)) - } - } - } - } - - checkStatus(intervals) - } } case class FileChecksProgress(totalFiles: Int, avMetadataProgressPercentage: Int, checksumProgressPercentage: Int, ffidMetadataProgressPercentage: Int) { diff --git a/app/controllers/FileChecksResultsController.scala b/app/controllers/FileChecksResultsController.scala index d83c82189..7b722b888 100644 --- a/app/controllers/FileChecksResultsController.scala +++ b/app/controllers/FileChecksResultsController.scala @@ -32,7 +32,7 @@ class FileChecksResultsController @Inject() ( val pageTitle = "Results of your checks" for { - fileCheck <- consignmentService.fileCheckProgress(consignmentId, request.token.bearerAccessToken) + fileCheck <- consignmentService.getConsignmentFileChecks(consignmentId, request.token.bearerAccessToken) parentFolder = fileCheck.parentFolder.getOrElse(throw new IllegalStateException(s"No parent folder found for consignment: '$consignmentId'")) reference <- consignmentService.getConsignmentRef(consignmentId, request.token.bearerAccessToken) } yield { @@ -57,5 +57,38 @@ class FileChecksResultsController @Inject() ( } } } + + def judgmentFileCheckResultsPage(consignmentId: UUID): Action[AnyContent] = judgmentTypeAction(consignmentId) { implicit request: Request[AnyContent] => + val pageTitle = "Results of checks" + for { + consignmentStatuses <- consignmentStatusService.getConsignmentStatuses(consignmentId, request.token.bearerAccessToken) + reference <- consignmentService.getConsignmentRef(consignmentId, request.token.bearerAccessToken) + exportStatus = consignmentStatusService.getStatusValues(consignmentStatuses, ExportType).values.headOption.flatten + result <- exportStatus match { + case Some(InProgressValue.value) | Some(CompletedValue.value) | Some(FailedValue.value) => + Future(Ok(views.html.transferAlreadyCompleted(consignmentId, reference, request.token.name, isJudgmentUser = true)).uncache()) + case None => + for { + fileCheck <- consignmentService.getConsignmentFileChecks(consignmentId, request.token.bearerAccessToken) + result <- + if (fileCheck.allChecksSucceeded) { + val token: BearerAccessToken = request.token.bearerAccessToken + val legalCustodyTransferConfirmation = FinalTransferConfirmationData(transferLegalCustody = true) + for { + _ <- confirmTransferService.addFinalTransferConfirmation(consignmentId, token, legalCustodyTransferConfirmation) + _ <- consignmentExportService.updateTransferInitiated(consignmentId, request.token.bearerAccessToken) + _ <- consignmentExportService.triggerExport(consignmentId, request.token.bearerAccessToken.toString) + res <- Future(Redirect(routes.TransferCompleteController.judgmentTransferComplete(consignmentId)).uncache()) + } yield res + } else { + Future(Ok(views.html.fileChecksResultsFailed(request.token.name, pageTitle, reference, isJudgmentUser = true)).uncache()) + } + } yield result + case _ => + throw new IllegalStateException(s"Unexpected Export status: $exportStatus for consignment $consignmentId") + } + } yield result + } } + case class ConsignmentFolderInfo(numberOfFiles: Int, parentFolder: String) diff --git a/app/controllers/ViewTransfersController.scala b/app/controllers/ViewTransfersController.scala index 7e027279f..61989db62 100644 --- a/app/controllers/ViewTransfersController.scala +++ b/app/controllers/ViewTransfersController.scala @@ -132,7 +132,7 @@ class ViewTransfersController @Inject() ( } val resultsUrl = if (judgmentType) { - routes.FileChecksController.judgmentCompleteTransfer(consignmentId).url + routes.FileChecksResultsController.judgmentFileCheckResultsPage(consignmentId).url } else { routes.FileChecksResultsController.fileCheckResultsPage(consignmentId).url } diff --git a/app/services/ConsignmentService.scala b/app/services/ConsignmentService.scala index 4456f7821..0565b255b 100644 --- a/app/services/ConsignmentService.scala +++ b/app/services/ConsignmentService.scala @@ -22,7 +22,7 @@ import graphql.codegen.GetConsignmentsForMetadataReview.{getConsignmentsForMetad import graphql.codegen.GetFileCheckProgress.{getFileCheckProgress => gfcp} import graphql.codegen.UpdateConsignmentSeriesId.updateConsignmentSeriesId import graphql.codegen.types._ -import graphql.codegen.{AddConsignment, GetConsignmentFilesMetadata} +import graphql.codegen.{AddConsignment, GetConsignmentFilesMetadata, GetFileCheckProgress} import services.ApiErrorHandling._ import services.ConsignmentService.{File, StatusTag} import uk.gov.nationalarchives.tdr.keycloak.Token @@ -38,6 +38,7 @@ class ConsignmentService @Inject() (val graphqlConfiguration: GraphQLConfigurati private val getConsignmentClient = graphqlConfiguration.getClient[getConsignment.Data, getConsignment.Variables]() private val getConsignmentFilesMetadataClient = graphqlConfiguration.getClient[gcfm.Data, gcfm.Variables]() private val addConsignmentClient = graphqlConfiguration.getClient[addConsignment.Data, addConsignment.Variables]() + private val getConsignmentFileCheckClient = graphqlConfiguration.getClient[gfcp.Data, gfcp.Variables]() private val getConsignmentFolderDetailsClient = graphqlConfiguration.getClient[getConsignmentFolderDetails.Data, getConsignmentFolderDetails.Variables]() private val getConsignmentSummaryClient = graphqlConfiguration.getClient[getConsignmentSummary.Data, getConsignmentSummary.Variables]() private val getConsignmentReferenceClient = graphqlConfiguration.getClient[getConsignmentReference.Data, getConsignmentReference.Variables]() @@ -121,6 +122,13 @@ class ConsignmentService @Inject() (val graphqlConfiguration: GraphQLConfigurati .map(data => data.addConsignment) } + def getConsignmentFileChecks(consignmentId: UUID, token: BearerAccessToken): Future[gfcp.GetConsignment] = { + val variables: gfcp.Variables = new GetFileCheckProgress.getFileCheckProgress.Variables(consignmentId) + + sendApiRequest(getConsignmentFileCheckClient, gfcp.document, token, variables) + .map(data => data.getConsignment.get) + } + def getConsignmentFolderInfo(consignmentId: UUID, token: BearerAccessToken): Future[getConsignmentFolderDetails.GetConsignment] = { val variables: getConsignmentFolderDetails.Variables = new getConsignmentFolderDetails.Variables(consignmentId) diff --git a/app/views/fileChecksProgressAlreadyConfirmed.scala.html b/app/views/fileChecksProgressAlreadyConfirmed.scala.html index 2f42ba37f..d7706f09a 100644 --- a/app/views/fileChecksProgressAlreadyConfirmed.scala.html +++ b/app/views/fileChecksProgressAlreadyConfirmed.scala.html @@ -21,7 +21,7 @@

@title

Continue diff --git a/app/views/judgment/judgmentFileChecksProgress.scala.html b/app/views/judgment/judgmentFileChecksProgress.scala.html index 1b956fbb1..14313bcfe 100644 --- a/app/views/judgment/judgmentFileChecksProgress.scala.html +++ b/app/views/judgment/judgmentFileChecksProgress.scala.html @@ -20,7 +20,7 @@

Checking your upload

- @form(routes.FileChecksController.judgmentCompleteTransfer(consignmentId), Symbol("id") -> "continue-transfer") { } + @form(routes.FileChecksResultsController.judgmentFileCheckResultsPage(consignmentId), Symbol("id") -> "file-checks-form") { }
@transferReference(consignmentRef, isJudgmentUser = true) diff --git a/build.sbt b/build.sbt index 20aca6718..7c1ce4979 100644 --- a/build.sbt +++ b/build.sbt @@ -66,8 +66,3 @@ excludeDependencies ++= Seq( ) pipelineStages := Seq(digest) - -excludeDependencies ++= Seq( - ExclusionRule(organization = "com.typesafe.akka"), - ExclusionRule(organization = "com.typesafe.play") -) diff --git a/conf/application.base.conf b/conf/application.base.conf index 8f1da89c8..9d1001e11 100644 --- a/conf/application.base.conf +++ b/conf/application.base.conf @@ -66,5 +66,3 @@ draftMetadata { } notificationSnsTopicArn = ${NOTIFICATION_SNS_TOPIC_ARN} -fileChecksTotalTimoutInSeconds = 480 -fileChecksTotalTimoutInSeconds = ${?FILE_CHECKS_TOTAL_TIMEOUT_IN_SECONDS} diff --git a/conf/application.local-base.conf b/conf/application.local-base.conf index 907c6e821..a9fbf3ff2 100644 --- a/conf/application.local-base.conf +++ b/conf/application.local-base.conf @@ -23,5 +23,3 @@ featureAccessBlock { blockDraftMetadataUpload=false blockMetadataReview=false } - -notificationSnsTopicArn = "arn:test-arn" diff --git a/conf/routes b/conf/routes index 02e6752ff..cd2d557be 100644 --- a/conf/routes +++ b/conf/routes @@ -75,7 +75,8 @@ GET /judgment/help GET /judgment/:consignmentId/before-uploading controllers.BeforeUploadingController.beforeUploading(consignmentId: java.util.UUID) GET /judgment/:consignmentId/upload controllers.UploadController.judgmentUploadPage(consignmentId: java.util.UUID) GET /judgment/:consignmentId/file-checks controllers.FileChecksController.judgmentFileChecksPage(consignmentId: java.util.UUID, uploadFailed: Option[String]) -GET /judgment/:consignmentId/continue-transfer controllers.FileChecksController.judgmentCompleteTransfer(consignmentId: java.util.UUID) +POST /judgment/:consignmentId/file-check-progress controllers.FileChecksController.fileCheckProgress(consignmentId: java.util.UUID) +GET /judgment/:consignmentId/file-checks-results controllers.FileChecksResultsController.judgmentFileCheckResultsPage(consignmentId: java.util.UUID) GET /judgment/:consignmentId/transfer-complete controllers.TransferCompleteController.judgmentTransferComplete(consignmentId: java.util.UUID) # Routes for TNA-User diff --git a/npm/src/checks/index.ts b/npm/src/checks/index.ts index 3c96d297d..e06d3b0e0 100644 --- a/npm/src/checks/index.ts +++ b/npm/src/checks/index.ts @@ -19,26 +19,21 @@ export class Checks { isJudgmentUser: boolean, goToNextPage: (formId: string) => void ) => { - if (isJudgmentUser) { - goToNextPage("#continue-transfer") - } else { - const intervalId: ReturnType = setInterval( - async () => { - const fileChecksProgress: IFileCheckProgress | Error = - await getFileChecksProgress() - if (!isError(fileChecksProgress)) { - const checksCompleted = haveFileChecksCompleted(fileChecksProgress) - if (checksCompleted) { - clearInterval(intervalId) - displayChecksCompletedBanner("file-checks") - } - } else { - return fileChecksProgress - } - }, - 5000 - ) - } + const intervalId: ReturnType = setInterval(async () => { + const fileChecksProgress: IFileCheckProgress | Error = + await getFileChecksProgress() + if (!isError(fileChecksProgress)) { + const checksCompleted = haveFileChecksCompleted(fileChecksProgress) + if (checksCompleted) { + clearInterval(intervalId) + isJudgmentUser + ? goToNextPage("#file-checks-form") + : displayChecksCompletedBanner("file-checks") + } + } else { + return fileChecksProgress + } + }, 5000) } updateDraftMetadataValidationProgress: () => void | Error = () => { diff --git a/npm/test/update-check-progress.test.ts b/npm/test/update-check-progress.test.ts index 2e159dbe5..092bc489b 100644 --- a/npm/test/update-check-progress.test.ts +++ b/npm/test/update-check-progress.test.ts @@ -99,20 +99,6 @@ const mockDisplayChecksHaveCompletedBanner: () => void = () => () => {} ) -test("'updateFileCheckProgress' calls goToNextPage for a judgment user without checks", async () => { - const consignmentId = "e25438db-4bfb-41c9-8fff-6f2e4cca6421" - mockGetCheckProgress.getConsignmentId.mockImplementation( - () => consignmentId - ) - - checks.updateFileCheckProgress(true, mockGoToNextPage) - await jest.runOnlyPendingTimers() - - expect(mockGetCheckProgress.getFileChecksProgress).not.toHaveBeenCalled() - expect(haveFileChecksCompleted).not.toHaveBeenCalled() - expect(mockGoToNextPage).toHaveBeenCalled() -}) - test("'updateFileCheckProgress' calls setInterval correctly", async () => { jest.spyOn(global, "setInterval") await checks.updateFileCheckProgress(false, mockGoToNextPage) @@ -279,3 +265,58 @@ test("'updateDraftMetadataValidationProgress' shows a standard user, no banner a expect(hasDraftMetadataValidationCompleted).toBeCalled() expect(displayChecksCompletedBanner).not.toBeCalled() }) + +test("'updateFileCheckProgress' calls goToNextPage for a judgment user, if all checks are complete", async () => { + const consignmentId = "e25438db-4bfb-41c9-8fff-6f2e4cca6421" + mockGetCheckProgress.getConsignmentId.mockImplementation( + () => consignmentId + ) + + mockGetFileChecksProgress("complete") + + mockVerifyChecksHaveCompleted.haveFileChecksCompleted.mockImplementation( + () => true + ) + + checks.updateFileCheckProgress(true, mockGoToNextPage) + await jest.runOnlyPendingTimers() + + expect(haveFileChecksCompleted).toBeCalled() + expect(mockGoToNextPage).toHaveBeenCalled() +}) + +test("'updateFileCheckProgress' does not call goToNextPage for a judgment user if the checks are in progress", async () => { + const consignmentId = "e25438db-4bfb-41c9-8fff-6f2e4cca6421" + mockGetCheckProgress.getConsignmentId.mockImplementation( + () => consignmentId + ) + mockGetFileChecksProgress("inProgress") + + mockVerifyChecksHaveCompleted.haveFileChecksCompleted.mockImplementation( + () => false + ) + + checks.updateFileCheckProgress(true, mockGoToNextPage) + await jest.runOnlyPendingTimers() + + expect(haveFileChecksCompleted).toBeCalled() + expect(mockGoToNextPage).not.toHaveBeenCalled() +}) + +test("'updateFileCheckProgress' does not call goToNextPage for a judgment user if no file checks information is returned", async () => { + const consignmentId = "e25438db-4bfb-41c9-8fff-6f2e4cca6421" + mockGetCheckProgress.getConsignmentId.mockImplementation( + () => consignmentId + ) + mockGetFileChecksProgress("noData") + + mockVerifyChecksHaveCompleted.haveFileChecksCompleted.mockImplementation( + () => false + ) + + checks.updateFileCheckProgress(true, mockGoToNextPage) + await jest.runOnlyPendingTimers() + + expect(haveFileChecksCompleted).toBeCalled() + expect(mockGoToNextPage).not.toHaveBeenCalled() +}) diff --git a/test/controllers/FileChecksControllerSpec.scala b/test/controllers/FileChecksControllerSpec.scala index 86c4d644f..2f213766e 100644 --- a/test/controllers/FileChecksControllerSpec.scala +++ b/test/controllers/FileChecksControllerSpec.scala @@ -1,10 +1,8 @@ package controllers -import cats.implicits.catsSyntaxOptionId import com.github.tomakehurst.wiremock.WireMockServer import com.github.tomakehurst.wiremock.client.WireMock._ -import com.github.tomakehurst.wiremock.stubbing.Scenario -import configuration.{GraphQLConfiguration, KeycloakConfiguration} +import configuration.GraphQLConfiguration import graphql.codegen.GetConsignmentStatus.getConsignmentStatus.GetConsignment.ConsignmentStatuses import graphql.codegen.GetFileCheckProgress.{getFileCheckProgress => fileCheck} import io.circe.Printer @@ -12,17 +10,14 @@ import io.circe.generic.auto._ import io.circe.syntax._ import org.mockito.ArgumentMatchers.anyString import org.mockito.Mockito.when -import org.pac4j.play.scala.SecurityComponents import org.scalatest.concurrent.ScalaFutures.convertScalaFuture import org.scalatest.prop.{TableDrivenPropertyChecks, TableFor1} -import play.api.Configuration -import play.api.libs.ws.WSClient import play.api.test.CSRFTokenHelper.CSRFRequest import play.api.test.FakeRequest -import play.api.test.Helpers.{status, status => playStatus, _} +import play.api.test.Helpers.{status => playStatus, _} import play.api.test.WsTestClient.InternalWSClient import services.Statuses.{CompletedValue, CompletedWithIssuesValue, UploadType} -import services.{BackendChecksService, ConfirmTransferService, ConsignmentExportService, ConsignmentService, ConsignmentStatusService} +import services.{BackendChecksService, ConsignmentService, ConsignmentStatusService} import testUtils.{CheckPageForStaticElements, FrontEndTestHelper} import java.time.{LocalDateTime, ZoneId, ZonedDateTime} @@ -57,35 +52,6 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper val checkPageForStaticElements = new CheckPageForStaticElements - def initialiseFileChecks( - keycloakConfiguration: KeycloakConfiguration, - controllerComponents: SecurityComponents = getAuthorisedSecurityComponents, - backendChecksService: Option[BackendChecksService] = None - ): FileChecksController = { - - val wsClient = mock[WSClient] - val config = mock[Configuration] - - val graphQLConfiguration = new GraphQLConfiguration(app.configuration) - val consignmentService = new ConsignmentService(graphQLConfiguration) - val consignmentStatusService = new ConsignmentStatusService(graphQLConfiguration) - val backendChecks = new BackendChecksService(new InternalWSClient("http", 9007), app.configuration) - val confirmTransferService = new ConfirmTransferService(graphQLConfiguration) - val consignmentExportService = new ConsignmentExportService(wsClient, config, graphQLConfiguration) - - new FileChecksController( - controllerComponents, - graphQLConfiguration, - keycloakConfiguration, - consignmentService, - frontEndInfoConfiguration, - backendChecksService.getOrElse(backendChecks), - consignmentStatusService, - confirmTransferService, - consignmentExportService - ) - } - forAll(fileChecks) { userType => "FileChecksController GET" should { val (pathName, keycloakConfiguration, expectedTitle, expectedHeading, expectedInstruction, expectedForm) = if (userType == "judgment") { @@ -124,17 +90,30 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper } s"render the $userType fileChecks page if the checks are incomplete" in { + val graphQLConfiguration = new GraphQLConfiguration(app.configuration) + val consignmentService = new ConsignmentService(graphQLConfiguration) + val consignmentStatusService = new ConsignmentStatusService(graphQLConfiguration) + val backendChecksService = new BackendChecksService(new InternalWSClient("http", 9007), app.configuration) val filesProcessedWithAntivirus = 6 val filesProcessedWithChecksum = 12 val filesProcessedWithFFID = 8 val dataString: String = progressData(filesProcessedWithAntivirus, filesProcessedWithChecksum, filesProcessedWithFFID, allChecksSucceeded = false) + val uploadStatus = List(ConsignmentStatuses(UUID.randomUUID(), UUID.randomUUID(), UploadType.id, CompletedValue.value, someDateTime, None)) + mockGetFileCheckProgress(dataString, userType) setConsignmentReferenceResponse(wiremockServer) setConsignmentStatusResponse(app.configuration, wiremockServer, consignmentStatuses = uploadStatus) - mockGetFileCheckProgress(dataString, userType) - val fileChecksController = initialiseFileChecks(keycloakConfiguration) + val fileChecksController = new FileChecksController( + getAuthorisedSecurityComponents, + graphQLConfiguration, + keycloakConfiguration, + consignmentService, + frontEndInfoConfiguration, + backendChecksService, + consignmentStatusService + ) val uploadFailed = "false" val fileChecksPage = if (userType == "judgment") { fileChecksController @@ -161,26 +140,39 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper } else { fileChecksPageAsString must include( """

For more information on these checks, please see our - | FAQ (opens in new tab) for this service. - |

""".stripMargin + | FAQ (opens in new tab) for this service. + |

""".stripMargin ) fileChecksPageAsString must include( """
- |

- | Important - |

- |
- |
- |

Your records have been checked

- |

Please click 'Continue' to see your results.

- |
""".stripMargin + |

+ | Important + |

+ | + |
+ |

Your records have been checked

+ |

Please click 'Continue' to see your results.

+ |
""".stripMargin ) - fileChecksPageAsString must include(expectedForm) } + fileChecksPageAsString must include(expectedForm) } s"return a redirect to the auth server with an unauthenticated $userType user" in { - val controller = initialiseFileChecks(keycloakConfiguration, getUnauthorisedSecurityComponents) + val graphQLConfiguration = new GraphQLConfiguration(app.configuration) + val consignmentService = new ConsignmentService(graphQLConfiguration) + val consignmentStatusService = new ConsignmentStatusService(graphQLConfiguration) + val backendChecksService = new BackendChecksService(new InternalWSClient("http", 9007), app.configuration) + val controller = + new FileChecksController( + getUnauthorisedSecurityComponents, + graphQLConfiguration, + getValidKeycloakConfiguration, + consignmentService, + frontEndInfoConfiguration, + backendChecksService, + consignmentStatusService + ) val fileChecksPage = controller.fileChecksPage(consignmentId, None).apply(FakeRequest(GET, s"/$pathName/$consignmentId/file-checks")) playStatus(fileChecksPage) mustBe FOUND @@ -188,8 +180,11 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper } s"render the $userType file checks complete page if the file checks are complete and all checks are successful" in { + val graphQLConfiguration = new GraphQLConfiguration(app.configuration) + val consignmentService = new ConsignmentService(graphQLConfiguration) + val consignmentStatusService = new ConsignmentStatusService(graphQLConfiguration) val backendChecksService = mock[BackendChecksService] - val dataString: String = progressData(filesProcessedWithAntivirus = 40, filesProcessedWithChecksum = 40, filesProcessedWithFFID = 40, allChecksSucceeded = true) + val dataString: String = progressData(40, 40, 40, allChecksSucceeded = true) val uploadStatus = List(ConsignmentStatuses(UUID.randomUUID(), UUID.randomUUID(), UploadType.id, InProgress.value, someDateTime, None)) when(backendChecksService.triggerBackendChecks(org.mockito.ArgumentMatchers.any(classOf[UUID]), anyString())).thenReturn(Future.successful(true)) @@ -198,8 +193,15 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper setConsignmentReferenceResponse(wiremockServer) setConsignmentStatusResponse(app.configuration, wiremockServer, consignmentStatuses = uploadStatus) - val fileChecksController = initialiseFileChecks(keycloakConfiguration, backendChecksService = backendChecksService.some) - + val fileChecksController = new FileChecksController( + getAuthorisedSecurityComponents, + graphQLConfiguration, + keycloakConfiguration, + consignmentService, + frontEndInfoConfiguration, + backendChecksService, + consignmentStatusService + ) val uploadFailed = "false" val fileChecksPage = if (userType == "judgment") { fileChecksController @@ -228,6 +230,10 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper } s"render the $userType file checks complete page if the file checks are complete and all checks are not successful" in { + val graphQLConfiguration = new GraphQLConfiguration(app.configuration) + val consignmentService = new ConsignmentService(graphQLConfiguration) + val consignmentStatusService = new ConsignmentStatusService(graphQLConfiguration) + val backendChecksService = new BackendChecksService(new InternalWSClient("http", 9007), app.configuration) val dataString: String = progressData(40, 40, 40, allChecksSucceeded = false) val uploadStatus = List(ConsignmentStatuses(UUID.randomUUID(), UUID.randomUUID(), UploadType.id, CompletedValue.value, someDateTime, None)) @@ -235,8 +241,15 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper setConsignmentStatusResponse(app.configuration, wiremockServer, consignmentStatuses = uploadStatus) setConsignmentReferenceResponse(wiremockServer) - val controller = initialiseFileChecks(keycloakConfiguration) - + val controller = new FileChecksController( + getAuthorisedSecurityComponents, + graphQLConfiguration, + keycloakConfiguration, + consignmentService, + frontEndInfoConfiguration, + backendChecksService, + consignmentStatusService + ) val fileChecksCompletePage = if (userType == "judgment") { controller.judgmentFileChecksPage(consignmentId, None).apply(FakeRequest(GET, s"/$pathName/$consignmentId/file-checks")) } else { @@ -257,7 +270,12 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper } s"render the $userType error page if the user upload fails and ensure consignment status is updated" in { + val graphQLConfiguration = new GraphQLConfiguration(app.configuration) + val consignmentService = new ConsignmentService(graphQLConfiguration) + val consignmentStatusService = new ConsignmentStatusService(graphQLConfiguration) + val backendChecksService = new BackendChecksService(new InternalWSClient("http", 9007), app.configuration) val filesProcessedWithAntivirus = 6 + val filesProcessedWithChecksum = 12 val filesProcessedWithFFID = 8 val dataString: String = progressData(filesProcessedWithAntivirus, filesProcessedWithChecksum, filesProcessedWithFFID, allChecksSucceeded = false) @@ -268,8 +286,15 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper setConsignmentReferenceResponse(wiremockServer) setConsignmentStatusResponse(app.configuration, wiremockServer, consignmentStatuses = uploadStatus) - val fileChecksController = initialiseFileChecks(keycloakConfiguration) - + val fileChecksController = new FileChecksController( + getAuthorisedSecurityComponents, + graphQLConfiguration, + keycloakConfiguration, + consignmentService, + frontEndInfoConfiguration, + backendChecksService, + consignmentStatusService + ) val uploadFailed = "true" val fileChecksPage = if (userType == "judgment") { fileChecksController @@ -299,6 +324,9 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper } s"render the $userType error page if the user upload succeeds but backendChecks fails to trigger" in { + val graphQLConfiguration = new GraphQLConfiguration(app.configuration) + val consignmentService = new ConsignmentService(graphQLConfiguration) + val consignmentStatusService = new ConsignmentStatusService(graphQLConfiguration) val backendChecksService = mock[BackendChecksService] val filesProcessedWithAntivirus = 6 @@ -313,8 +341,15 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper setConsignmentReferenceResponse(wiremockServer) setConsignmentStatusResponse(app.configuration, wiremockServer, consignmentStatuses = uploadStatus) - val fileChecksController = initialiseFileChecks(keycloakConfiguration, backendChecksService = backendChecksService.some) - + val fileChecksController = new FileChecksController( + getAuthorisedSecurityComponents, + graphQLConfiguration, + keycloakConfiguration, + consignmentService, + frontEndInfoConfiguration, + backendChecksService, + consignmentStatusService + ) val uploadFailed = "false" val fileChecksPage = if (userType == "judgment") { fileChecksController @@ -344,6 +379,9 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper } s"render the $userType error page if the user upload status is 'CompletedWithIssues'" in { + val graphQLConfiguration = new GraphQLConfiguration(app.configuration) + val consignmentService = new ConsignmentService(graphQLConfiguration) + val consignmentStatusService = new ConsignmentStatusService(graphQLConfiguration) val backendChecksService = mock[BackendChecksService] val filesProcessedWithAntivirus = 6 @@ -358,8 +396,15 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper setConsignmentReferenceResponse(wiremockServer) setConsignmentStatusResponse(app.configuration, wiremockServer, consignmentStatuses = uploadStatus) - val fileChecksController = initialiseFileChecks(keycloakConfiguration) - + val fileChecksController = new FileChecksController( + getAuthorisedSecurityComponents, + graphQLConfiguration, + keycloakConfiguration, + consignmentService, + frontEndInfoConfiguration, + backendChecksService, + consignmentStatusService + ) val uploadFailed = "false" val fileChecksPage = if (userType == "judgment") { fileChecksController @@ -393,7 +438,19 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper "FileChecksController fileCheckProgress" should { "call the fileCheckProgress endpoint" in { - val controller = initialiseFileChecks(getValidKeycloakConfiguration) + val graphQLConfiguration: GraphQLConfiguration = new GraphQLConfiguration(app.configuration) + val consignmentService: ConsignmentService = new ConsignmentService(graphQLConfiguration) + val consignmentStatusService = new ConsignmentStatusService(graphQLConfiguration) + val backendChecksService = new BackendChecksService(new InternalWSClient("http", 9007), app.configuration) + val controller = new FileChecksController( + getAuthorisedSecurityComponents, + graphQLConfiguration, + getValidStandardUserKeycloakConfiguration, + consignmentService, + frontEndInfoConfiguration, + backendChecksService, + consignmentStatusService + ) mockGetFileCheckProgress(progressData(1, 1, 1, allChecksSucceeded = true), "standard") @@ -407,7 +464,19 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper } "throw an error if the API returns an error" in { - val controller = initialiseFileChecks(getValidKeycloakConfiguration) + val graphQLConfiguration: GraphQLConfiguration = new GraphQLConfiguration(app.configuration) + val consignmentService: ConsignmentService = new ConsignmentService(graphQLConfiguration) + val consignmentStatusService = new ConsignmentStatusService(graphQLConfiguration) + val backendChecksService = new BackendChecksService(new InternalWSClient("http", 9007), app.configuration) + val controller = new FileChecksController( + getAuthorisedSecurityComponents, + graphQLConfiguration, + getValidStandardUserKeycloakConfiguration, + consignmentService, + frontEndInfoConfiguration, + backendChecksService, + consignmentStatusService + ) wiremockServer.stubFor( post(urlEqualTo("/graphql")) @@ -424,144 +493,6 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper } } - "FileChecksController judgmentCompleteTransfer" should { - - s"return a redirect to the auth server if an unauthenticated user tries to access the judgment complete transfer page" in { - val fileChecksController = initialiseFileChecks(getValidJudgmentUserKeycloakConfiguration, getUnauthorisedSecurityComponents) - val recordChecksResultsPage = fileChecksController - .judgmentCompleteTransfer(consignmentId) - .apply(FakeRequest(GET, s"/judgment/$consignmentId/continue-transfer")) - - status(recordChecksResultsPage) mustBe FOUND - redirectLocation(recordChecksResultsPage).get must startWith("/auth/realms/tdr/protocol/openid-connect/auth") - } - - s"return the judgment error page if some file checks have failed" in { - - setConsignmentReferenceResponse(wiremockServer) - setConsignmentStatusResponse(app.configuration, wiremockServer) - val dataString: String = progressData(filesProcessedWithAntivirus = 40, filesProcessedWithChecksum = 40, filesProcessedWithFFID = 40, allChecksSucceeded = false) - mockGetFileCheckProgress(dataString, "judgment") - - val fileChecksController = initialiseFileChecks(getValidKeycloakConfiguration) - val recordCheckResultsPage = fileChecksController.judgmentCompleteTransfer(consignmentId).apply(FakeRequest(GET, s"/judgment/$consignmentId/continue-transfer")) - val resultsPageAsString = contentAsString(recordCheckResultsPage) - - status(recordCheckResultsPage) mustBe OK - - checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = "judgment") - verifyFileChecksResultPage(resultsPageAsString) - } - - s"return the judgment error page if file checks have failed with PasswordProtected" in { - setConsignmentReferenceResponse(wiremockServer) - setConsignmentStatusResponse(app.configuration, wiremockServer) - val fileStatus = "PasswordProtected" - val dataString: String = - progressData(filesProcessedWithAntivirus = 40, filesProcessedWithChecksum = 40, filesProcessedWithFFID = 40, allChecksSucceeded = false, List(fileStatus)) - mockGetFileCheckProgress(dataString, "judgment") - - val fileChecksController = initialiseFileChecks(getValidKeycloakConfiguration) - val recordCheckResultsPage = fileChecksController.judgmentCompleteTransfer(consignmentId).apply(FakeRequest(GET, s"/judgment/$consignmentId/continue-transfer")) - - val resultsPageAsString = contentAsString(recordCheckResultsPage) - - status(recordCheckResultsPage) mustBe OK - checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = "judgment") - verifyFileChecksResultPage(resultsPageAsString) - } - - s"return the judgment error page if file checks have failed with Zip" in { - setConsignmentReferenceResponse(wiremockServer) - setConsignmentStatusResponse(app.configuration, wiremockServer) - val fileStatus = "Zip" - val dataString: String = - progressData(filesProcessedWithAntivirus = 40, filesProcessedWithChecksum = 40, filesProcessedWithFFID = 40, allChecksSucceeded = false, List(fileStatus)) - mockGetFileCheckProgress(dataString, "judgment") - - val fileChecksController = initialiseFileChecks(getValidKeycloakConfiguration) - val recordCheckResultsPage = fileChecksController.judgmentCompleteTransfer(consignmentId).apply(FakeRequest(GET, s"/judgment/$consignmentId/continue-transfer")) - - val resultsPageAsString = contentAsString(recordCheckResultsPage) - - status(recordCheckResultsPage) mustBe OK - checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = "judgment") - verifyFileChecksResultPage(resultsPageAsString) - } - - s"return the judgment error page if file checks have failed with PasswordProtected and Zip" in { - setConsignmentReferenceResponse(wiremockServer) - setConsignmentStatusResponse(app.configuration, wiremockServer) - val fileStatuses = List("PasswordProtected", "Zip") - val dataString: String = - progressData(filesProcessedWithAntivirus = 40, filesProcessedWithChecksum = 40, filesProcessedWithFFID = 40, allChecksSucceeded = false, fileStatuses) - mockGetFileCheckProgress(dataString, "judgment") - - val fileChecksController = initialiseFileChecks(getValidKeycloakConfiguration) - val recordCheckResultsPage = fileChecksController.judgmentCompleteTransfer(consignmentId).apply(FakeRequest(GET, s"/judgment/$consignmentId/continue-transfer")) - - val resultsPageAsString = contentAsString(recordCheckResultsPage) - - status(recordCheckResultsPage) mustBe OK - - checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = "judgment") - verifyFileChecksResultPage(resultsPageAsString) - } - } - - private def verifyFileChecksResultPage(resultsPageAsString: String) = { - val expectedFailureReturnButton: String = - """ - | Return to start - | """.stripMargin - - val expectedFailureTitle: String = - """

- | There is a problem - |

""".stripMargin - - val expectedTitle = "Results of checks - Transfer Digital Records - GOV.UK" - val expectedHeading = """

Results of checks

""" - val expectedGenericErrorMessage = """

Your file has failed our checks. Please try again. If this continues, contact us at - | - | nationalArchives.email - | - |

""".stripMargin - - resultsPageAsString must include(expectedTitle) - resultsPageAsString must include(expectedHeading) - resultsPageAsString must include(expectedFailureTitle) - resultsPageAsString must include(expectedGenericErrorMessage) - resultsPageAsString must include(expectedFailureReturnButton) - } - - forAll(consignmentStatuses) { consignmentStatus => - s"render the 'transfer has already been confirmed' page with an authenticated judgment user if export status is '$consignmentStatus'" in { - val consignmentId = UUID.fromString("c2efd3e6-6664-4582-8c28-dcf891f60e68") - val userType = "judgment" - val fileChecksController = initialiseFileChecks(getValidJudgmentUserKeycloakConfiguration) - val consignmentStatuses = List(ConsignmentStatuses(UUID.randomUUID(), UUID.randomUUID(), "Export", consignmentStatus, someDateTime, None)) - setConsignmentStatusResponse(app.configuration, wiremockServer, consignmentStatuses = consignmentStatuses) - setConsignmentTypeResponse(wiremockServer, userType) - setConsignmentReferenceResponse(wiremockServer) - - val transferAlreadyCompletedPage = - fileChecksController.judgmentCompleteTransfer(consignmentId).apply(FakeRequest(GET, s"/judgment/$consignmentId/continue-transfer").withCSRFToken) - - val transferAlreadyCompletedPageAsString = contentAsString(transferAlreadyCompletedPage) - - status(transferAlreadyCompletedPage) mustBe OK - contentType(transferAlreadyCompletedPage) mustBe Some("text/html") - headers(transferAlreadyCompletedPage) mustBe TreeMap("Cache-Control" -> "no-store, must-revalidate") - - checkPageForStaticElements.checkContentOfPagesThatUseMainScala(transferAlreadyCompletedPageAsString, userType = userType) - transferAlreadyCompletedPageAsString must include("Your transfer has already been completed - Transfer Digital Records - GOV.UK") - transferAlreadyCompletedPageAsString must include("""

Your transfer has already been completed

""") - transferAlreadyCompletedPageAsString must include("""

Click 'Continue' to see the confirmation page again or return to the start.

""") - transferAlreadyCompletedPageAsString must include(s"""href="/$userType/$consignmentId/transfer-complete">Continue""") - } - } - private def mockGetFileCheckProgress(dataString: String, userType: String) = { setConsignmentTypeResponse(wiremockServer, userType) wiremockServer.stubFor( @@ -574,7 +505,20 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper forAll(userChecks) { (user, url) => s"The $url upload page" should { s"return 403 if the url doesn't match the consignment type" in { - val controller = initialiseFileChecks(getValidKeycloakConfiguration) + val graphQLConfiguration = new GraphQLConfiguration(app.configuration) + val consignmentService = new ConsignmentService(graphQLConfiguration) + val consignmentStatusService = new ConsignmentStatusService(graphQLConfiguration) + val backendChecksService = new BackendChecksService(new InternalWSClient("http", 9007), app.configuration) + + val controller = new FileChecksController( + getAuthorisedSecurityComponents, + graphQLConfiguration, + user, + consignmentService, + frontEndInfoConfiguration, + backendChecksService, + consignmentStatusService + ) val fileChecksPage = url match { case "judgment" => @@ -593,24 +537,18 @@ class FileChecksControllerSpec extends FrontEndTestHelper with TableDrivenProper } } - private def progressData( - filesProcessedWithAntivirus: Int, - filesProcessedWithChecksum: Int, - filesProcessedWithFFID: Int, - allChecksSucceeded: Boolean, - fileStatusList: List[String] = List("Success") - ): String = { + private def progressData(filesProcessedWithAntivirus: Int, filesProcessedWithChecksum: Int, filesProcessedWithFFID: Int, allChecksSucceeded: Boolean): String = { val client = new GraphQLConfiguration(app.configuration).getClient[fileCheck.Data, fileCheck.Variables]() val antivirusProgress = fileCheck.GetConsignment.FileChecks.AntivirusProgress(filesProcessedWithAntivirus) val checksumProgress = fileCheck.GetConsignment.FileChecks.ChecksumProgress(filesProcessedWithChecksum) val ffidProgress = fileCheck.GetConsignment.FileChecks.FfidProgress(filesProcessedWithFFID) val fileChecks = fileCheck.GetConsignment.FileChecks(antivirusProgress, checksumProgress, ffidProgress) - val fileStatuses = fileStatusList.map(fileStatus => fileCheck.GetConsignment.Files(Some(fileStatus))) + val fileStatus = List(fileCheck.GetConsignment.Files(Some("Success"))) val data: client.GraphqlData = client.GraphqlData( Some( fileCheck.Data( Some( - fileCheck.GetConsignment(allChecksSucceeded, Option(""), totalFiles, fileStatuses, fileChecks) + fileCheck.GetConsignment(allChecksSucceeded, Option(""), totalFiles, fileStatus, fileChecks) ) ) ) diff --git a/test/controllers/FileChecksResultsControllerSpec.scala b/test/controllers/FileChecksResultsControllerSpec.scala index 573162e30..00495a01f 100644 --- a/test/controllers/FileChecksResultsControllerSpec.scala +++ b/test/controllers/FileChecksResultsControllerSpec.scala @@ -5,6 +5,7 @@ import configuration.{ApplicationConfig, GraphQLConfiguration, KeycloakConfigura import graphql.codegen.GetConsignmentFiles.getConsignmentFiles.GetConsignment.Files import graphql.codegen.GetConsignmentFiles.getConsignmentFiles.GetConsignment.Files.Metadata import graphql.codegen.GetConsignmentFiles.{getConsignmentFiles => gcf} +import graphql.codegen.GetConsignmentStatus.getConsignmentStatus.GetConsignment.ConsignmentStatuses import graphql.codegen.GetFileCheckProgress.getFileCheckProgress.GetConsignment.FileChecks import graphql.codegen.GetFileCheckProgress.getFileCheckProgress.GetConsignment.FileChecks.{AntivirusProgress, ChecksumProgress, FfidProgress} import graphql.codegen.GetFileCheckProgress.getFileCheckProgress.{Data, GetConsignment, Variables} @@ -23,9 +24,11 @@ import play.api.test.Helpers._ import play.api.test.WsTestClient.InternalWSClient import services.{ConfirmTransferService, ConsignmentExportService, ConsignmentService, ConsignmentStatusService} import testUtils.{CheckPageForStaticElements, FrontEndTestHelper} +import uk.gov.nationalarchives.tdr.GraphQLClient import java.time.{LocalDateTime, ZoneId, ZonedDateTime} import java.util.UUID +import scala.collection.immutable.TreeMap import scala.concurrent.ExecutionContext class FileChecksResultsControllerSpec extends FrontEndTestHelper { @@ -73,20 +76,6 @@ class FileChecksResultsControllerSpec extends FrontEndTestHelper { """

| There is a problem |

""".stripMargin - val expectedTitle = "Results of your checks - Transfer Digital Records - GOV.UK" - val expectedHeading = """

Results of your checks

""" - val expectedGenericErrorMessage = """

- | One or more files you uploaded have failed our checks. Contact us at - | nationalArchives.email - | if the problem persists. - |

- |

Possible failure causes:

- |""".stripMargin "FileChecksResultsController GET after file check success" should { "render the fileChecksResults page with the confirmation box for a standard user" in { @@ -106,7 +95,7 @@ class FileChecksResultsControllerSpec extends FrontEndTestHelper { val recordCheckResultsPage = fileCheckResultsController .fileCheckResultsPage(consignmentId) - .apply(FakeRequest(GET, s"/consignment/$consignmentId/file-checks-results").withCSRFToken) + .apply(FakeRequest(GET, s"/consignment/$consignmentId/file-checks").withCSRFToken) val resultsPageAsString = contentAsString(recordCheckResultsPage) @@ -122,140 +111,253 @@ class FileChecksResultsControllerSpec extends FrontEndTestHelper { resultsPageAsString must include(expectedSuccessMessage) resultsPageAsString must include regex buttonToProgress } - } - - "FileChecksResultsController GET" should { - s"return a redirect to the auth server if an unauthenticated user tries to access the standard file checks page" in { - val fileCheckResultsController = instantiateController(getUnauthorisedSecurityComponents, getValidStandardUserKeycloakConfiguration) - val recordChecksResultsPage = fileCheckResultsController - .fileCheckResultsPage(consignmentId) - .apply(FakeRequest(GET, s"consignment/$consignmentId/file-checks-results")) + "return a redirect to judgments checked passed url for a judgements user" in { + val fileCheckResultsController = setUpFileChecksController("judgment", getValidJudgmentUserKeycloakConfiguration) - status(recordChecksResultsPage) mustBe FOUND - redirectLocation(recordChecksResultsPage).get must startWith("/auth/realms/tdr/protocol/openid-connect/auth") - } + // Export status not set + val consignmentStatuses = List(ConsignmentStatuses(UUID.randomUUID(), UUID.randomUUID(), "Upload", "Completed", someDateTime, None)) + setConsignmentStatusResponse(app.configuration, wiremockServer, consignmentStatuses = consignmentStatuses) + setConsignmentTypeResponse(wiremockServer, "judgment") + setConsignmentReferenceResponse(wiremockServer) - s"return an error if an authenticated user tries to get information for a consignment they don't own from the standard file checks page" in { - val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, getValidStandardUserKeycloakConfiguration) - val exampleApiResponse = "{\"fileChecksData\":{" + - "\"getConsignment\":null}," + - "\"errors\":[{" + - "\"message\":\"User '7bee3c41-c059-46f6-8e9b-9ba44b0489b7' does not own consignment '0a3f617c-04e8-41c2-9f24-99622a779528'\"," + - "\"path\":[\"getConsignment\"],\"locations\":[{" + - "\"column\":3,\"line\":2}]," + - "\"extensions\":{" + - "\"code\":\"NOT_AUTHORISED\"}}]}" + // final transfer configuration + stubFinalTransferConfirmationResponseWithServer(wiremockServer, consignmentId) - wiremockServer.stubFor( - post(urlEqualTo("/graphql")) - .willReturn(okJson(exampleApiResponse)) + // initiated transfer + stubUpdateTransferInitiatedResponse(wiremockServer, consignmentId) + // start export + wiremockExportServer.stubFor( + post(urlEqualTo(s"/export/$consignmentId")) + .willReturn(ok()) ) - val results: Throwable = fileCheckResultsController - .fileCheckResultsPage(consignmentId) - .apply( - FakeRequest(GET, s"consignment/$consignmentId/file-checks-results") - ) - .failed - .futureValue - - results.getMessage mustBe "User '7bee3c41-c059-46f6-8e9b-9ba44b0489b7' does not own consignment '0a3f617c-04e8-41c2-9f24-99622a779528'" + val recordCheckResultsPage = fileCheckResultsController + .judgmentFileCheckResultsPage(consignmentId) + .apply(FakeRequest(GET, s"/consignment/$consignmentId/file-checks").withCSRFToken) + status(recordCheckResultsPage) mustBe 303 + redirectLocation(recordCheckResultsPage).get must be("/judgment/0a3f617c-04e8-41c2-9f24-99622a779528/transfer-complete") } + "render an error when there is an error from the api for judgment after file checks passed" in { + val fileCheckResultsController = setUpFileChecksController("judgment", getValidJudgmentUserKeycloakConfiguration) - s"return the standard error page if some file checks have failed" in { - val graphQLConfiguration = new GraphQLConfiguration(app.configuration) + // Export status not set + val consignmentStatuses = List(ConsignmentStatuses(UUID.randomUUID(), UUID.randomUUID(), "Upload", "Completed", someDateTime, None)) + setConsignmentStatusResponse(app.configuration, wiremockServer, consignmentStatuses = consignmentStatuses) + setConsignmentTypeResponse(wiremockServer, "judgment") + setConsignmentReferenceResponse(wiremockServer) - setConsignmentStatusResponse(app.configuration, wiremockServer) - val fileStatus = List(gfcp.GetConsignment.Files(Some("fileStatusValue"))) + // final transfer configuration with errors + stubFinalTransferConfirmationResponseWithServer(wiremockServer, consignmentId, List(GraphQLClient.Error("Error", Nil, Nil, None))) - val data = Data( - Option( - GetConsignment(allChecksSucceeded = false, Option("parentFolder"), 1, fileStatus, FileChecks(AntivirusProgress(1), ChecksumProgress(1), FfidProgress(1))) - ) + // initiated transfer + stubUpdateTransferInitiatedResponse(wiremockServer, consignmentId) + // start export + wiremockExportServer.stubFor( + post(urlEqualTo(s"/export/$consignmentId")) + .willReturn(ok()) ) - val client = graphQLConfiguration.getClient[Data, Variables]() - val fileStatusResponse: String = client.GraphqlData(Option(data), List()).asJson.printWith(Printer(dropNullValues = false, "")) - mockGraphqlResponse("standard", fileStatusResponse) - setConsignmentReferenceResponse(wiremockServer) - - val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, getValidStandardUserKeycloakConfiguration) val recordCheckResultsPage = fileCheckResultsController - .fileCheckResultsPage(consignmentId) - .apply(FakeRequest(GET, s"/consignment/$consignmentId/file-checks-results")) - val resultsPageAsString = contentAsString(recordCheckResultsPage) + .judgmentFileCheckResultsPage(consignmentId) + .apply(FakeRequest(GET, s"/consignment/$consignmentId/file-checks").withCSRFToken) - status(recordCheckResultsPage) mustBe OK - - checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = "standard") - resultsPageAsString must include(expectedTitle) - resultsPageAsString must include(expectedHeading) - resultsPageAsString must include(expectedFailureTitle) - resultsPageAsString must include(expectedGenericErrorMessage) - resultsPageAsString must include(expectedFailureReturnButton) + val failure: Throwable = recordCheckResultsPage.failed.futureValue + failure mustBe an[Exception] } + } - s"return the passwordProtected standard error page if file checks have failed with PasswordProtected" in { - val graphQLConfiguration = new GraphQLConfiguration(app.configuration) - setConsignmentStatusResponse(app.configuration, wiremockServer) - val fileStatus = List(gfcp.GetConsignment.Files(Some("PasswordProtected"))) + forAll(userTypes) { userType => + "FileChecksResultsController GET" should { + + val (pathName, keycloakConfiguration, expectedTitle, expectedHeading, expectedSuccessMessage, buttonToProgress, expectedGenericErrorMessage) = if (userType == "judgment") { + ( + "judgment", + getValidJudgmentUserKeycloakConfiguration, + "Results of checks - Transfer Digital Records - GOV.UK", + """

Results of checks

""", + s"""

Your uploaded file 'test file.docx' has now been validated.

+ |

Click 'Continue' to transfer it to The National Archives.

""".stripMargin, + s"""
+ | + | + |
""".stripMargin, + """

Your file has failed our checks. Please try again. If this continues, contact us at + | + | nationalArchives.email + | + |

""".stripMargin + ) + } else { + ( + "consignment", + getValidStandardUserKeycloakConfiguration, + "Results of your checks - Transfer Digital Records - GOV.UK", + """

Results of your checks

""", + """

+ | Your folder 'parentFolder' containing 1 record has been uploaded and checked. + |

+ |

You can leave and return to this upload at any time from the View transfers page.

""".stripMargin, + s""" + | Next + | """.stripMargin, + """

+ | One or more files you uploaded have failed our checks. Contact us at + | nationalArchives.email + | if the problem persists. + |

+ |

Possible failure causes:

+ |""".stripMargin + ) + } - val data = Data( - Option( - GetConsignment(allChecksSucceeded = false, Option("parentFolder"), 1, fileStatus, FileChecks(AntivirusProgress(1), ChecksumProgress(1), FfidProgress(1))) + s"return a redirect to the auth server if an unauthenticated user tries to access the $userType file checks page" in { + val fileCheckResultsController = instantiateController(getUnauthorisedSecurityComponents, getValidKeycloakConfiguration) + val recordChecksResultsPage = fileCheckResultsController + .fileCheckResultsPage(consignmentId) + .apply(FakeRequest(GET, s"consignment/$consignmentId/file-checks-results")) + + status(recordChecksResultsPage) mustBe FOUND + redirectLocation(recordChecksResultsPage).get must startWith("/auth/realms/tdr/protocol/openid-connect/auth") + } + + s"return an error if an authenticated user tries to get information for a consignment they don't own from the $userType file checks page" in { + val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, getValidKeycloakConfiguration) + val exampleApiResponse = "{\"fileChecksData\":{" + + "\"getConsignment\":null}," + + "\"errors\":[{" + + "\"message\":\"User '7bee3c41-c059-46f6-8e9b-9ba44b0489b7' does not own consignment '0a3f617c-04e8-41c2-9f24-99622a779528'\"," + + "\"path\":[\"getConsignment\"],\"locations\":[{" + + "\"column\":3,\"line\":2}]," + + "\"extensions\":{" + + "\"code\":\"NOT_AUTHORISED\"}}]}" + + wiremockServer.stubFor( + post(urlEqualTo("/graphql")) + .willReturn(okJson(exampleApiResponse)) ) - ) - val client = graphQLConfiguration.getClient[Data, Variables]() - val fileStatusResponse: String = client.GraphqlData(Option(data), List()).asJson.printWith(Printer(dropNullValues = false, "")) - mockGraphqlResponse("standard", fileStatusResponse) - setConsignmentReferenceResponse(wiremockServer) + val results: Throwable = fileCheckResultsController + .fileCheckResultsPage(consignmentId) + .apply( + FakeRequest(GET, s"consignment/$consignmentId/file-checks-results") + ) + .failed + .futureValue - val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, getValidStandardUserKeycloakConfiguration) - val recordCheckResultsPage = fileCheckResultsController - .fileCheckResultsPage(consignmentId) - .apply(FakeRequest(GET, s"/consignment/$consignmentId/file-checks-results")) - val resultsPageAsString = contentAsString(recordCheckResultsPage) + results.getMessage mustBe "User '7bee3c41-c059-46f6-8e9b-9ba44b0489b7' does not own consignment '0a3f617c-04e8-41c2-9f24-99622a779528'" + } - resultsPageAsString must include( - """

Your folder contains one or more password protected files.

""" + - """

We cannot accept password protected files. Once removed or replaced, try uploading your folder again.

""" - ) + s"return the $userType error page if some file checks have failed" in { + val graphQLConfiguration = new GraphQLConfiguration(app.configuration) - status(recordCheckResultsPage) mustBe OK + setConsignmentStatusResponse(app.configuration, wiremockServer) + val fileStatus = List(gfcp.GetConsignment.Files(Some("fileStatusValue"))) - checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = "standard") - resultsPageAsString must include(expectedTitle) - resultsPageAsString must include(expectedHeading) - resultsPageAsString must include(expectedFailureTitle) - resultsPageAsString must include(expectedFailureReturnButton) - } - - s"return the zip standard error page if file checks have failed with Zip" in { - val graphQLConfiguration = new GraphQLConfiguration(app.configuration) - setConsignmentStatusResponse(app.configuration, wiremockServer) - val fileStatus = List(gfcp.GetConsignment.Files(Some("Zip"))) - - val data = Data( - Option( - GetConsignment(allChecksSucceeded = false, Option("parentFolder"), 1, fileStatus, FileChecks(AntivirusProgress(1), ChecksumProgress(1), FfidProgress(1))) + val data = Data( + Option( + GetConsignment(allChecksSucceeded = false, Option("parentFolder"), 1, fileStatus, FileChecks(AntivirusProgress(1), ChecksumProgress(1), FfidProgress(1))) + ) ) - ) - val client = graphQLConfiguration.getClient[Data, Variables]() - val fileStatusResponse: String = client.GraphqlData(Option(data), List()).asJson.printWith(Printer(dropNullValues = false, "")) - - mockGraphqlResponse("standard", fileStatusResponse) - setConsignmentReferenceResponse(wiremockServer) - - val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, getValidStandardUserKeycloakConfiguration) - val recordCheckResultsPage = fileCheckResultsController - .fileCheckResultsPage(consignmentId) - .apply(FakeRequest(GET, s"/consignment/$consignmentId/file-checks-results")) - val resultsPageAsString = contentAsString(recordCheckResultsPage) - - resultsPageAsString must include( - """

Your folder contains one or more zip files.

+ val client = graphQLConfiguration.getClient[Data, Variables]() + val fileStatusResponse: String = client.GraphqlData(Option(data), List()).asJson.printWith(Printer(dropNullValues = false, "")) + + mockGraphqlResponse(userType, fileStatusResponse) + setConsignmentReferenceResponse(wiremockServer) + + val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, keycloakConfiguration) + val recordCheckResultsPage = { + if (userType == "judgment") { fileCheckResultsController.judgmentFileCheckResultsPage(consignmentId) } + else { fileCheckResultsController.fileCheckResultsPage(consignmentId) } + }.apply(FakeRequest(GET, s"/$pathName/$consignmentId/file-checks")) + val resultsPageAsString = contentAsString(recordCheckResultsPage) + + status(recordCheckResultsPage) mustBe OK + + checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = userType) + resultsPageAsString must include(expectedTitle) + resultsPageAsString must include(expectedHeading) + resultsPageAsString must include(expectedFailureTitle) + resultsPageAsString must include(expectedGenericErrorMessage) + resultsPageAsString must include(expectedFailureReturnButton) + } + + s"return the passwordProtected $userType error page if file checks have failed with PasswordProtected" in { + val graphQLConfiguration = new GraphQLConfiguration(app.configuration) + setConsignmentStatusResponse(app.configuration, wiremockServer) + val fileStatus = List(gfcp.GetConsignment.Files(Some("PasswordProtected"))) + + val data = Data( + Option( + GetConsignment(allChecksSucceeded = false, Option("parentFolder"), 1, fileStatus, FileChecks(AntivirusProgress(1), ChecksumProgress(1), FfidProgress(1))) + ) + ) + val client = graphQLConfiguration.getClient[Data, Variables]() + val fileStatusResponse: String = client.GraphqlData(Option(data), List()).asJson.printWith(Printer(dropNullValues = false, "")) + + mockGraphqlResponse(userType, fileStatusResponse) + setConsignmentReferenceResponse(wiremockServer) + + val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, keycloakConfiguration) + val recordCheckResultsPage = { + if (userType == "judgment") { fileCheckResultsController.judgmentFileCheckResultsPage(consignmentId) } + else { fileCheckResultsController.fileCheckResultsPage(consignmentId) } + }.apply(FakeRequest(GET, s"/$pathName/$consignmentId/file-checks")) + val resultsPageAsString = contentAsString(recordCheckResultsPage) + + if (userType == "judgment") { + resultsPageAsString must include(expectedGenericErrorMessage) + } else { + resultsPageAsString must include( + """

Your folder contains one or more password protected files.

""" + + """

We cannot accept password protected files. Once removed or replaced, try uploading your folder again.

""" + ) + } + + status(recordCheckResultsPage) mustBe OK + + checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = userType) + resultsPageAsString must include(expectedTitle) + resultsPageAsString must include(expectedHeading) + resultsPageAsString must include(expectedFailureTitle) + resultsPageAsString must include(expectedFailureReturnButton) + } + + s"return the zip $userType error page if file checks have failed with Zip" in { + val graphQLConfiguration = new GraphQLConfiguration(app.configuration) + setConsignmentStatusResponse(app.configuration, wiremockServer) + val fileStatus = List(gfcp.GetConsignment.Files(Some("Zip"))) + + val data = Data( + Option( + GetConsignment(allChecksSucceeded = false, Option("parentFolder"), 1, fileStatus, FileChecks(AntivirusProgress(1), ChecksumProgress(1), FfidProgress(1))) + ) + ) + val client = graphQLConfiguration.getClient[Data, Variables]() + val fileStatusResponse: String = client.GraphqlData(Option(data), List()).asJson.printWith(Printer(dropNullValues = false, "")) + + mockGraphqlResponse(userType, fileStatusResponse) + setConsignmentReferenceResponse(wiremockServer) + + val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, keycloakConfiguration) + val recordCheckResultsPage = { + if (userType == "judgment") { fileCheckResultsController.judgmentFileCheckResultsPage(consignmentId) } + else { fileCheckResultsController.fileCheckResultsPage(consignmentId) } + }.apply(FakeRequest(GET, s"/$pathName/$consignmentId/file-checks")) + val resultsPageAsString = contentAsString(recordCheckResultsPage) + + if (userType == "judgment") { + resultsPageAsString must include(expectedGenericErrorMessage) + } else { + resultsPageAsString must include( + """

Your folder contains one or more zip files.

| We cannot accept zip files and similar archival package file formats. | These commonly have file extensions such as .zip, .iso, .7z, .rar and others. | please see our @@ -265,58 +367,99 @@ class FileChecksResultsControllerSpec extends FrontEndTestHelper { | for a full list. | Either remove or unpack your zip and archival package files and try uploading again. |

""".stripMargin - ) - - status(recordCheckResultsPage) mustBe OK - - checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = "standard") - resultsPageAsString must include(expectedTitle) - resultsPageAsString must include(expectedHeading) - resultsPageAsString must include(expectedFailureTitle) - resultsPageAsString must include(expectedFailureReturnButton) - } - - s"return the general standard error page if file checks have failed with PasswordProtected and Zip" in { - val graphQLConfiguration = new GraphQLConfiguration(app.configuration) - setConsignmentStatusResponse(app.configuration, wiremockServer) - val fileStatus = List(gfcp.GetConsignment.Files(Some("PasswordProtected")), gfcp.GetConsignment.Files(Some("Zip"))) - - val data = Data( - Option( - GetConsignment(allChecksSucceeded = false, Option("parentFolder"), 1, fileStatus, FileChecks(AntivirusProgress(1), ChecksumProgress(1), FfidProgress(1))) + ) + } + + status(recordCheckResultsPage) mustBe OK + + checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = userType) + resultsPageAsString must include(expectedTitle) + resultsPageAsString must include(expectedHeading) + resultsPageAsString must include(expectedFailureTitle) + resultsPageAsString must include(expectedFailureReturnButton) + } + + s"return the general $userType error page if file checks have failed with PasswordProtected and Zip" in { + val graphQLConfiguration = new GraphQLConfiguration(app.configuration) + setConsignmentStatusResponse(app.configuration, wiremockServer) + val fileStatus = List(gfcp.GetConsignment.Files(Some("PasswordProtected")), gfcp.GetConsignment.Files(Some("Zip"))) + + val data = Data( + Option( + GetConsignment(allChecksSucceeded = false, Option("parentFolder"), 1, fileStatus, FileChecks(AntivirusProgress(1), ChecksumProgress(1), FfidProgress(1))) + ) ) - ) - val client = graphQLConfiguration.getClient[Data, Variables]() - val fileStatusResponse: String = client.GraphqlData(Option(data), List()).asJson.printWith(Printer(dropNullValues = false, "")) + val client = graphQLConfiguration.getClient[Data, Variables]() + val fileStatusResponse: String = client.GraphqlData(Option(data), List()).asJson.printWith(Printer(dropNullValues = false, "")) + + mockGraphqlResponse(userType, fileStatusResponse) + setConsignmentReferenceResponse(wiremockServer) + + val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, keycloakConfiguration) + val recordCheckResultsPage = { + if (userType == "judgment") { fileCheckResultsController.judgmentFileCheckResultsPage(consignmentId) } + else { fileCheckResultsController.fileCheckResultsPage(consignmentId) } + }.apply(FakeRequest(GET, s"/$pathName/$consignmentId/file-checks")) + val resultsPageAsString = contentAsString(recordCheckResultsPage) + + status(recordCheckResultsPage) mustBe OK + + checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = userType) + resultsPageAsString must include(expectedTitle) + resultsPageAsString must include(expectedHeading) + resultsPageAsString must include(expectedFailureTitle) + resultsPageAsString must include(expectedGenericErrorMessage) + resultsPageAsString must include(expectedFailureReturnButton) + } + } + } - mockGraphqlResponse("standard", fileStatusResponse) + forAll(consignmentStatuses) { consignmentStatus => + s"render the 'transfer has already been confirmed' page with an authenticated judgment user if export status is '$consignmentStatus'" in { + val consignmentId = UUID.fromString("c2efd3e6-6664-4582-8c28-dcf891f60e68") + val userType = "judgment" + val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, getValidJudgmentUserKeycloakConfiguration) + val consignmentStatuses = List(ConsignmentStatuses(UUID.randomUUID(), UUID.randomUUID(), "Export", consignmentStatus, someDateTime, None)) + setConsignmentStatusResponse(app.configuration, wiremockServer, consignmentStatuses = consignmentStatuses) + setConsignmentTypeResponse(wiremockServer, userType) setConsignmentReferenceResponse(wiremockServer) - val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, getValidStandardUserKeycloakConfiguration) - val recordCheckResultsPage = fileCheckResultsController - .fileCheckResultsPage(consignmentId) - .apply(FakeRequest(GET, s"/consignment/$consignmentId/file-checks-results")) - val resultsPageAsString = contentAsString(recordCheckResultsPage) + val transferAlreadyCompletedPage = fileCheckResultsController + .judgmentFileCheckResultsPage(consignmentId) + .apply(FakeRequest(GET, s"/$userType/$consignmentId/file-checks").withCSRFToken) - status(recordCheckResultsPage) mustBe OK + val transferAlreadyCompletedPageAsString = contentAsString(transferAlreadyCompletedPage) - checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = "standard") - resultsPageAsString must include(expectedTitle) - resultsPageAsString must include(expectedHeading) - resultsPageAsString must include(expectedFailureTitle) - resultsPageAsString must include(expectedGenericErrorMessage) - resultsPageAsString must include(expectedFailureReturnButton) - } + status(transferAlreadyCompletedPage) mustBe OK + contentType(transferAlreadyCompletedPage) mustBe Some("text/html") + headers(transferAlreadyCompletedPage) mustBe TreeMap("Cache-Control" -> "no-store, must-revalidate") - s"return 403 if the url doesn't match the consignment type" in { - val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, getValidJudgmentUserKeycloakConfiguration) - mockGraphqlResponse(consignmentType = "judgment") - val fileCheckResultsPage = - fileCheckResultsController - .fileCheckResultsPage(consignmentId) - .apply(FakeRequest(GET, s"/consignment/$consignmentId/file-checks-results")) + checkPageForStaticElements.checkContentOfPagesThatUseMainScala(transferAlreadyCompletedPageAsString, userType = userType) + transferAlreadyCompletedPageAsString must include("Your transfer has already been completed - Transfer Digital Records - GOV.UK") + transferAlreadyCompletedPageAsString must include("""

Your transfer has already been completed

""") + transferAlreadyCompletedPageAsString must include("""

Click 'Continue' to see the confirmation page again or return to the start.

""") + transferAlreadyCompletedPageAsString must include(s"""href="/$userType/$consignmentId/transfer-complete">Continue""") + } + } - status(fileCheckResultsPage) mustBe FORBIDDEN + forAll(userChecks) { (user, url) => + s"The $url upload page" should { + s"return 403 if the url doesn't match the consignment type" in { + val fileCheckResultsController = instantiateController(getAuthorisedSecurityComponents, user) + val fileCheckResultsPage = url match { + case "judgment" => + mockGraphqlResponse(consignmentType = "standard") + fileCheckResultsController + .judgmentFileCheckResultsPage(consignmentId) + .apply(FakeRequest(GET, s"/judgment/$consignmentId/file-checks-results")) + case "consignment" => + mockGraphqlResponse(consignmentType = "judgment") + fileCheckResultsController + .fileCheckResultsPage(consignmentId) + .apply(FakeRequest(GET, s"/consignment/$consignmentId/file-checks-results")) + } + status(fileCheckResultsPage) mustBe FORBIDDEN + } } } diff --git a/test/testUtils/ConsignmentStatusesOptions.scala b/test/testUtils/ConsignmentStatusesOptions.scala index 565b78714..7a23d7c82 100644 --- a/test/testUtils/ConsignmentStatusesOptions.scala +++ b/test/testUtils/ConsignmentStatusesOptions.scala @@ -507,7 +507,7 @@ object ConsignmentStatusesOptions { generateStatuses( clientChecksCompleted ++ uploadCompleted ++ antivirusFailed ), - "/continue-transfer", + "/file-checks-results", "Failed", "View errors" ), @@ -516,7 +516,7 @@ object ConsignmentStatusesOptions { generateStatuses( clientChecksCompleted ++ uploadCompleted ++ antivirusWithIssues ), - "/continue-transfer", + "/file-checks-results", "Failed", "View errors" ), @@ -543,7 +543,7 @@ object ConsignmentStatusesOptions { generateStatuses( clientChecksCompleted ++ uploadCompleted ++ antivirusCompleted ++ checksumFailed ), - "/continue-transfer", + "/file-checks-results", "Failed", "View errors" ), @@ -552,7 +552,7 @@ object ConsignmentStatusesOptions { generateStatuses( clientChecksCompleted ++ uploadCompleted ++ antivirusCompleted ++ checksumWithIssues ), - "/continue-transfer", + "/file-checks-results", "Failed", "View errors" ), @@ -579,7 +579,7 @@ object ConsignmentStatusesOptions { generateStatuses( clientChecksCompleted ++ uploadCompleted ++ antivirusCompleted ++ checksumCompleted ++ ffidFailed ), - "/continue-transfer", + "/file-checks-results", "Failed", "View errors" ), @@ -588,7 +588,7 @@ object ConsignmentStatusesOptions { generateStatuses( clientChecksCompleted ++ uploadCompleted ++ antivirusCompleted ++ checksumCompleted ++ ffidWithIssues ), - "/continue-transfer", + "/file-checks-results", "Failed", "View errors" ), @@ -597,7 +597,7 @@ object ConsignmentStatusesOptions { generateStatuses( clientChecksCompleted ++ uploadCompleted ++ antivirusCompleted ++ checksumCompleted ++ ffidCompleted ), - "/continue-transfer", + "/file-checks-results", "In Progress", "Resume transfer" ),