Skip to content

Commit

Permalink
Tdrd 84 automate full judgments workflow (#3828)
Browse files Browse the repository at this point in the history
* Automate judgment - transfer complete after successful checks
  • Loading branch information
ian-hoyle authored Apr 10, 2024
1 parent 48cbb03 commit c97c1d2
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 147 deletions.
2 changes: 2 additions & 0 deletions app/configuration/ApplicationConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class ApplicationConfig @Inject() (configuration: Configuration) {

val blockDraftMetadataUpload: Boolean = configuration.get[Boolean]("featureAccessBlock.blockDraftMetadataUpload")

val blockAutomateJudgmentTransfers: Boolean = configuration.get[Boolean]("featureAccessBlock.blockAutomateJudgmentTransfers")

val metadataValidationBaseUrl: String = configuration.get[String]("metadatavalidation.baseUrl")

val s3Endpoint: String = configuration.get[String]("s3.endpoint")
Expand Down
3 changes: 3 additions & 0 deletions app/controllers/ConfirmTransferController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ class ConfirmTransferController @Inject() (
}
} yield res
}

def judgmentChecksPassedSubmit(consignmentId: UUID): Action[AnyContent] = finalJudgmentTransferConfirmationSubmit(consignmentId: UUID)

}

case class ConsignmentSummaryData(seriesCode: String, transferringBody: String, totalFiles: Int, consignmentReference: String)
Expand Down
17 changes: 11 additions & 6 deletions app/controllers/FileChecksResultsController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class FileChecksResultsController @Inject() (

def judgmentFileCheckResultsPage(consignmentId: UUID): Action[AnyContent] = judgmentTypeAction(consignmentId) { implicit request: Request[AnyContent] =>
val pageTitle = "Results of checks"
val blockAutomateJudgmentTransfers = applicationConfig.blockAutomateJudgmentTransfers
for {
consignmentStatuses <- consignmentStatusService.getConsignmentStatuses(consignmentId, request.token.bearerAccessToken)
reference <- consignmentService.getConsignmentRef(consignmentId, request.token.bearerAccessToken)
Expand All @@ -69,12 +70,16 @@ class FileChecksResultsController @Inject() (
fileCheck <- consignmentService.getConsignmentFileChecks(consignmentId, request.token.bearerAccessToken)
result <-
if (fileCheck.allChecksSucceeded) {
consignmentService
.getConsignmentFilesData(consignmentId, request.token.bearerAccessToken)
.flatMap(files => {
val filename = files.files.head.metadata.clientSideOriginalFilePath.get
Future(Ok(views.html.judgment.judgmentFileChecksResults(filename, pageTitle, consignmentId, reference, request.token.name)).uncache())
})
if (blockAutomateJudgmentTransfers) {
consignmentService
.getConsignmentFilesData(consignmentId, request.token.bearerAccessToken)
.flatMap(files => {
val filename = files.files.head.metadata.clientSideOriginalFilePath.get
Future(Ok(views.html.judgment.judgmentFileChecksResults(filename, pageTitle, consignmentId, reference, request.token.name)).uncache())
})
} else {
Future(Redirect(routes.ConfirmTransferController.judgmentChecksPassedSubmit(consignmentId)).uncache())
}
} else {
Future(Ok(views.html.fileChecksResultsFailed(request.token.name, pageTitle, reference, isJudgmentUser = true)).uncache())
}
Expand Down
1 change: 1 addition & 0 deletions conf/application.base.conf
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,5 @@ draft_metadata_s3_bucket_name = ${DRAFT_METADATA_S3_BUCKET_NAME}

featureAccessBlock {
blockDraftMetadataUpload=${BLOCK_DRAFT_METADATA_UPLOAD}
blockAutomateJudgmentTransfers=${BLOCK_AUTOMATE_JUDGMENT_TRANSFERS}
}
1 change: 1 addition & 0 deletions conf/application.local-base.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ draft_metadata_s3_bucket_name = "tdr-draft-metadata-intg"

featureAccessBlock {
blockDraftMetadataUpload=false
blockAutomateJudgmentTransfers=false
}
1 change: 1 addition & 0 deletions conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,5 @@ GET /judgment/:consignmentId/file-checks
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)
POST /judgment/:consignmentId/file-checks-results controllers.ConfirmTransferController.finalJudgmentTransferConfirmationSubmit(consignmentId: java.util.UUID)
GET /judgment/:consignmentId/checks-passed controllers.ConfirmTransferController.judgmentChecksPassedSubmit(consignmentId: java.util.UUID)
GET /judgment/:consignmentId/transfer-complete controllers.TransferCompleteController.judgmentTransferComplete(consignmentId: java.util.UUID)
165 changes: 113 additions & 52 deletions test/controllers/FileChecksResultsControllerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,83 @@ class FileChecksResultsControllerSpec extends FrontEndTestHelper {
| There is a problem
| </h2>""".stripMargin

"FileChecksResultsController GET after file check success" should {
"render the fileChecksResults page with the confirmation box for a standard user" in {

val expectedSuccessMessage: String =
s""" <h3 class="govuk-notification-banner__heading">
| Your folder 'parentFolder' containing 1 record has been uploaded and checked.
| </h3>
| <p class="govuk-body">You can leave and return to this upload at any time from the <a class="govuk-notification-banner__link" href="/view-transfers">View transfers</a> page.</p>""".stripMargin

val buttonToProgress: String =
s""" <a class="govuk-button" href="/consignment/$consignmentId/additional-metadata/entry-method" role="button" draggable="false" data-module="govuk-button">
| Next
| </a>""".stripMargin

val fileCheckResultsController = setUpFileChecksController("standard", getValidStandardUserKeycloakConfiguration)

val recordCheckResultsPage = fileCheckResultsController
.fileCheckResultsPage(consignmentId)
.apply(FakeRequest(GET, s"/consignment/$consignmentId/file-checks").withCSRFToken)

val resultsPageAsString = contentAsString(recordCheckResultsPage)

status(recordCheckResultsPage) mustBe 200
contentType(recordCheckResultsPage) mustBe Some("text/html")

checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = "standard")
resultsPageAsString must include("<title>Results of your checks - Transfer Digital Records - GOV.UK</title>")
resultsPageAsString must include("""<h1 class="govuk-heading-l">Results of your checks</h1>""")
resultsPageAsString must include(expectedSuccessSummaryTitle)
resultsPageAsString.replaceAll(twoOrMoreSpaces, "") must include(expectedSuccessWarningText(warningMsg).replaceAll(twoOrMoreSpaces, ""))

resultsPageAsString must include(expectedSuccessMessage)
resultsPageAsString must include regex buttonToProgress
}

"render the fileChecksResults page with the confirmation box for a judgement user when block automate judgment" in {

val expectedSuccessMessage: String =
s""" <p class="govuk-body">Your uploaded file 'test file.docx' has now been validated.</p>
| <p class="govuk-body">Click 'Continue' to transfer it to The National Archives.</p>""".stripMargin

val buttonToProgress: String =
s""" <form method="post" action="/judgment/$consignmentId/file-checks-results">
| <input type="hidden" name="csrfToken" value="[0-9a-z\\-]+"/>
| <button class="govuk-button" type="submit" role="button" draggable="false">
| Continue
| </button>
| </form>""".stripMargin

val fileCheckResultsController = setUpFileChecksController("judgment", getValidJudgmentUserKeycloakConfiguration, blockAutomateJudgmentTransfers = true)
val recordCheckResultsPage = fileCheckResultsController
.judgmentFileCheckResultsPage(consignmentId)
.apply(FakeRequest(GET, s"/consignment/$consignmentId/file-checks").withCSRFToken)
status(recordCheckResultsPage) mustBe 200
val resultsPageAsString = contentAsString(recordCheckResultsPage)

status(recordCheckResultsPage) mustBe 200
contentType(recordCheckResultsPage) mustBe Some("text/html")

checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = "judgment")

resultsPageAsString must include("<title>Results of checks - Transfer Digital Records - GOV.UK</title>")
resultsPageAsString must include("""<h1 class="govuk-heading-l">Results of checks</h1>""")
resultsPageAsString must include(expectedSuccessMessage)
resultsPageAsString must include regex buttonToProgress
}

"return a redirect to judgments checked passed url for a judgements user" in {
val fileCheckResultsController = setUpFileChecksController("judgment", getValidJudgmentUserKeycloakConfiguration)
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/checks-passed")
}
}

forAll(userTypes) { userType =>
"FileChecksResultsController GET" should {

Expand Down Expand Up @@ -122,57 +199,6 @@ class FileChecksResultsControllerSpec extends FrontEndTestHelper {
)
}

s"render the $userType fileChecksResults page with the confirmation box" in {
val graphQLConfiguration = new GraphQLConfiguration(app.configuration)

setConsignmentStatusResponse(app.configuration, wiremockServer)
val fileStatus = List(gfcp.GetConsignment.Files(Some("Success")))

val fileChecksData = gfcp.Data(
Option(
GetConsignment(allChecksSucceeded = true, Option("parentFolder"), 1, fileStatus, FileChecks(AntivirusProgress(1), ChecksumProgress(1), FfidProgress(1)))
)
)

val filePathData = gcf.Data(
Option(gcf.GetConsignment(List(Files(UUID.randomUUID(), Option(""), Option(""), Option(UUID.randomUUID()), Metadata(Some("test file.docx")), Nil))))
)

val getFileChecksProgressClient = graphQLConfiguration.getClient[gfcp.Data, gfcp.Variables]()
val getConsignmentFilesClient = graphQLConfiguration.getClient[gcf.Data, gcf.Variables]()
val fileStatusResponse: String =
getFileChecksProgressClient.GraphqlData(Option(fileChecksData), List()).asJson.printWith(Printer(dropNullValues = false, ""))
val filePathResponse: String =
getConsignmentFilesClient.GraphqlData(Option(filePathData), List()).asJson.printWith(Printer(dropNullValues = false, ""))

mockGraphqlResponse(userType, fileStatusResponse, filePathResponse)
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").withCSRFToken)
val resultsPageAsString = contentAsString(recordCheckResultsPage)

status(recordCheckResultsPage) mustBe 200
contentType(recordCheckResultsPage) mustBe Some("text/html")

checkPageForStaticElements.checkContentOfPagesThatUseMainScala(resultsPageAsString, userType = userType)
resultsPageAsString must include(expectedTitle)
resultsPageAsString must include(expectedHeading)
if (userType != "judgment") {
resultsPageAsString must include(expectedSuccessSummaryTitle)
resultsPageAsString.replaceAll(twoOrMoreSpaces, "") must include(expectedSuccessWarningText(warningMsg).replaceAll(twoOrMoreSpaces, ""))
}
resultsPageAsString must include(expectedSuccessMessage)
resultsPageAsString must include regex buttonToProgress
}

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
Expand Down Expand Up @@ -436,8 +462,14 @@ class FileChecksResultsControllerSpec extends FrontEndTestHelper {
setConsignmentTypeResponse(wiremockServer, consignmentType)
}

private def instantiateController(securityComponent: SecurityComponents, keycloakConfiguration: KeycloakConfiguration, blockDraftMetadataUpload: Boolean = false) = {
private def instantiateController(
securityComponent: SecurityComponents,
keycloakConfiguration: KeycloakConfiguration,
blockDraftMetadataUpload: Boolean = false,
blockAutomateJudgmentTransfers: Boolean = false
) = {
when(configuration.get[Boolean]("featureAccessBlock.blockDraftMetadataUpload")).thenReturn(blockDraftMetadataUpload)
when(configuration.get[Boolean]("featureAccessBlock.blockAutomateJudgmentTransfers")).thenReturn(blockAutomateJudgmentTransfers)
val graphQLConfiguration = new GraphQLConfiguration(app.configuration)
val consignmentService = new ConsignmentService(graphQLConfiguration)
val consignmentStatusService = new ConsignmentStatusService(graphQLConfiguration)
Expand All @@ -451,4 +483,33 @@ class FileChecksResultsControllerSpec extends FrontEndTestHelper {
applicationConfig
)
}
def setUpFileChecksController(consignmentType: String, keyCloakConfig: KeycloakConfiguration, blockAutomateJudgmentTransfers: Boolean = false): FileChecksResultsController = {
val graphQLConfiguration = new GraphQLConfiguration(app.configuration)

setConsignmentStatusResponse(app.configuration, wiremockServer)
val fileStatus = List(gfcp.GetConsignment.Files(Some("Success")))

val fileChecksData = gfcp.Data(
Option(
GetConsignment(allChecksSucceeded = true, Option("parentFolder"), 1, fileStatus, FileChecks(AntivirusProgress(1), ChecksumProgress(1), FfidProgress(1)))
)
)

val filePathData = gcf.Data(
Option(gcf.GetConsignment(List(Files(UUID.randomUUID(), Option(""), Option(""), Option(UUID.randomUUID()), Metadata(Some("test file.docx")), Nil))))
)

val getFileChecksProgressClient = graphQLConfiguration.getClient[gfcp.Data, gfcp.Variables]()
val getConsignmentFilesClient = graphQLConfiguration.getClient[gcf.Data, gcf.Variables]()
val fileStatusResponse: String =
getFileChecksProgressClient.GraphqlData(Option(fileChecksData), List()).asJson.printWith(Printer(dropNullValues = false, ""))
val filePathResponse: String =
getConsignmentFilesClient.GraphqlData(Option(filePathData), List()).asJson.printWith(Printer(dropNullValues = false, ""))

mockGraphqlResponse(consignmentType, fileStatusResponse, filePathResponse)
setConsignmentReferenceResponse(wiremockServer)

instantiateController(getAuthorisedSecurityComponents, keyCloakConfig, blockAutomateJudgmentTransfers = blockAutomateJudgmentTransfers)

}
}
Loading

0 comments on commit c97c1d2

Please sign in to comment.