From 22af3eb7768140ee722cd10552d446a30ecdbd80 Mon Sep 17 00:00:00 2001 From: Mark Kingsbury Date: Wed, 25 Sep 2024 10:04:38 +0100 Subject: [PATCH 01/13] TDRD-367: reload file checks page every five minutes while checksCompleted is false --- npm/src/checks/index.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/npm/src/checks/index.ts b/npm/src/checks/index.ts index 53668992a..baa1c75de 100644 --- a/npm/src/checks/index.ts +++ b/npm/src/checks/index.ts @@ -41,6 +41,15 @@ export class Checks { if (isJudgmentUser) { this.checkJudgmentTransferProgress(goToNextPage) } else { + + const refreshPageIntervalId: ReturnType = setInterval( + async () => { + clearInterval(intervalId) + window.location.reload() + }, + 300000 + ) + const intervalId: ReturnType = setInterval( async () => { const fileChecksProgress: IFileCheckProgress | Error = @@ -49,9 +58,11 @@ export class Checks { const checksCompleted = haveFileChecksCompleted(fileChecksProgress) if (checksCompleted) { clearInterval(intervalId) + clearInterval(refreshPageIntervalId) displayChecksCompletedBanner("file-checks") } } else { + //TODO: i think clearInterval(refreshPageIntervalId) if error yeah? return fileChecksProgress } }, From a7b5d2a02b2faaf2a8cebcec27e6f2a684be97d9 Mon Sep 17 00:00:00 2001 From: Mark Kingsbury Date: Wed, 25 Sep 2024 11:10:43 +0100 Subject: [PATCH 02/13] TDRD-367: prettier --- npm/src/checks/index.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/npm/src/checks/index.ts b/npm/src/checks/index.ts index baa1c75de..9fd32efc9 100644 --- a/npm/src/checks/index.ts +++ b/npm/src/checks/index.ts @@ -41,13 +41,12 @@ export class Checks { if (isJudgmentUser) { this.checkJudgmentTransferProgress(goToNextPage) } else { - const refreshPageIntervalId: ReturnType = setInterval( - async () => { - clearInterval(intervalId) - window.location.reload() - }, - 300000 + async () => { + clearInterval(intervalId) + window.location.reload() + }, + 300000 ) const intervalId: ReturnType = setInterval( From 48976468817a7c2607ea0ff62dfd11b155953aec Mon Sep 17 00:00:00 2001 From: thanhz Date: Tue, 1 Oct 2024 11:55:57 +0100 Subject: [PATCH 03/13] TDRD-297 Top level folder UI changes (#4183) Move top level folder + content changes --- app/views/judgment/judgmentUpload.scala.html | 2 +- app/views/standard/upload.scala.html | 26 ++++----- npm/css-src/sass/_drag-and-drop.scss | 7 ++- .../update-and-display-success-message.ts | 13 ++++- npm/src/upload/form/upload-form.ts | 6 ++- npm/test/upload-form-files.test.ts | 8 ++- .../html-for-upload-forms.ts | 54 ++++++++++--------- .../upload-form-utils/mock-upload-form-dom.ts | 5 +- test/controllers/UploadControllerSpec.scala | 7 ++- 9 files changed, 80 insertions(+), 48 deletions(-) diff --git a/app/views/judgment/judgmentUpload.scala.html b/app/views/judgment/judgmentUpload.scala.html index ed0cce353..037c1e6a2 100644 --- a/app/views/judgment/judgmentUpload.scala.html +++ b/app/views/judgment/judgmentUpload.scala.html @@ -38,7 +38,7 @@

-
+
-
-
-

The folder (containing ) has been selected.

+
+
+

The folder (containing ) has been selected.

Remove  selected files
- -

For information on what metadata will be captured during upload, visit the FAQ (opens in new tab).

-
-
-
- - +
+

For information on what metadata will be captured during upload, visit the FAQ (opens in new tab).

-
-
-

The folder (containing ) has been selected.

+
+
+

The folder (containing ) has been selected.

Remove  selected files
- -

For more information on what metadata will be captured during the upload please visit our FAQ’s page

-
-
-
+
+
-
-
-
-
- - -
-
-
-
+
+
+

The folder (containing ) has been selected.

+ Remove  selected files +
+ + +
- |
""".stripMargin + playStatus(confirmTransferPage) mustBe OK + contentType(confirmTransferPage) mustBe Some("text/html") + checkConfirmTransferContent(confirmTransferPageAsString, consignmentSummaryResponse) + } + + "render the confirm transfer page with an authenticated user when all relevant statuses are 'Completed'" in { + val client = new GraphQLConfiguration(app.configuration).getClient[gcs.Data, gcs.Variables]() + val controller = instantiateConfirmTransferController(getAuthorisedSecurityComponents) + val consignmentStatuses = List( + ConsignmentStatuses(UUID.randomUUID(), UUID.randomUUID(), "Series", "Completed", someDateTime, None), + ConsignmentStatuses(UUID.randomUUID(), UUID.randomUUID(), "TransferAgreement", "Completed", someDateTime, None), + ConsignmentStatuses(UUID.randomUUID(), UUID.randomUUID(), "Upload", "Completed", someDateTime, None), + ConsignmentStatuses(UUID.randomUUID(), UUID.randomUUID(), "ClientChecks", "Completed", someDateTime, None) ) + setConsignmentStatusResponse(app.configuration, wiremockServer, consignmentStatuses = consignmentStatuses) + + val consignmentSummaryResponse: gcs.GetConsignment = getConsignmentSummaryResponse + val data: client.GraphqlData = client.GraphqlData(Some(gcs.Data(Some(consignmentSummaryResponse))), List()) + val dataString: String = data.asJson.printWith(Printer(dropNullValues = false, "")) + mockGraphqlConsignmentSummaryResponse(dataString) + val confirmTransferPage = controller + .confirmTransfer(consignmentId) + .apply(FakeRequest(GET, s"/consignment/$consignmentId/confirm-transfer").withCSRFToken) + + val confirmTransferPageAsString = contentAsString(confirmTransferPage) + + playStatus(confirmTransferPage) mustBe OK + contentType(confirmTransferPage) mustBe Some("text/html") + checkConfirmTransferContent(confirmTransferPageAsString, consignmentSummaryResponse) checkPageForStaticElements.checkContentOfPagesThatUseMainScala(confirmTransferPageAsString, userType = "standard") formTester.checkHtmlForOptionAndItsAttributes(confirmTransferPageAsString, Map()) } @@ -622,9 +647,21 @@ class ConfirmTransferControllerSpec extends FrontEndTestHelper { setConsignmentTypeResponse(wiremockServer, consignmentType) } + private def getApplicationConfig(blockSkipMetadataReview: Boolean): ApplicationConfig = { + val config: Map[String, ConfigValue] = ConfigFactory + .load() + .withValue("featureAccessBlock.blockSkipMetadataReview", ConfigValueFactory.fromAnyRef(blockSkipMetadataReview)) + .entrySet() + .asScala + .map(e => e.getKey -> e.getValue) + .toMap + new ApplicationConfig(Configuration.from(config)) + } + private def instantiateConfirmTransferController( securityComponents: SecurityComponents, - keycloakConfiguration: KeycloakConfiguration = getValidStandardUserKeycloakConfiguration + keycloakConfiguration: KeycloakConfiguration = getValidStandardUserKeycloakConfiguration, + blockSkipMetadataReview: Boolean = false ) = { val graphQLConfiguration = new GraphQLConfiguration(app.configuration) val confirmTransferService = new ConfirmTransferService(graphQLConfiguration) @@ -639,6 +676,7 @@ class ConfirmTransferControllerSpec extends FrontEndTestHelper { confirmTransferService, exportService(app.configuration), consignmentStatusService, + getApplicationConfig(blockSkipMetadataReview), langs ) } @@ -713,4 +751,92 @@ class ConfirmTransferControllerSpec extends FrontEndTestHelper { s"""href="/$transferType/$consignmentId/transfer-complete">Continue""".stripMargin ) } + + private def checkConfirmTransferContent(confirmTransferPageAsString: String, consignmentSummaryResponse: gcs.GetConsignment) = { + confirmTransferPageAsString must include("Confirm transfer - Transfer Digital Records - GOV.UK") + confirmTransferPageAsString must include(s"""Back""") + confirmTransferPageAsString must include("""

Confirm transfer

""") + + confirmTransferPageAsString must include( + """
+ |
+ |

+ | notification.savedProgress.title + |

+ |
+ |
+ |

+ | notification.savedProgress.heading + |

+ |

notification.savedProgress.metadataInfo

+ |
+ |
""".stripMargin + ) + + confirmTransferPageAsString must include("""

Here is a summary of the records you have uploaded.

""") + + confirmTransferPageAsString must include( + """
+ | Series reference + |
""".stripMargin + ) + + confirmTransferPageAsString must include( + s"""
+ | ${consignmentSummaryResponse.seriesName.get} + |
""".stripMargin + ) + + confirmTransferPageAsString must include( + """
+ | Consignment reference + |
""".stripMargin + ) + + confirmTransferPageAsString must include( + s"""
+ | ${consignmentSummaryResponse.consignmentReference} + |
""".stripMargin + ) + + confirmTransferPageAsString must include( + s"""
+ | Transferring body + |
""".stripMargin + ) + + confirmTransferPageAsString must include( + s"""
+ | ${consignmentSummaryResponse.transferringBodyName.get} + |
""".stripMargin + ) + + confirmTransferPageAsString must include( + s"""
+ | Files uploaded for transfer + |
""".stripMargin + ) + + confirmTransferPageAsString must include( + s"""
+ | ${consignmentSummaryResponse.totalFiles} files uploaded + |
""".stripMargin + ) + + confirmTransferPageAsString must include( + s"""""" + ) + + confirmTransferPageAsString must include regex ( + s"""""" + ) + + confirmTransferPageAsString must include( + s"""
+ | + |
""".stripMargin + ) + } } From 55cc2dcf06222793e1df93b7c0ed43e2fb68505f Mon Sep 17 00:00:00 2001 From: ian-hoyle Date: Wed, 9 Oct 2024 09:48:54 +0100 Subject: [PATCH 06/13] Added tests for messages from properties file (#4205) Added properties for UTF_8 failure details and action. Also added tests to check messages in properties files are correct --- ...DraftMetadataChecksResultsController.scala | 19 +-- conf/messages | 2 + ...tMetadataChecksResultsControllerSpec.scala | 117 +++++++----------- 3 files changed, 61 insertions(+), 77 deletions(-) diff --git a/app/controllers/DraftMetadataChecksResultsController.scala b/app/controllers/DraftMetadataChecksResultsController.scala index 4f28fbffc..26f5d7400 100644 --- a/app/controllers/DraftMetadataChecksResultsController.scala +++ b/app/controllers/DraftMetadataChecksResultsController.scala @@ -6,7 +6,7 @@ import controllers.util.ExcelUtils import controllers.util.MetadataProperty.filePath import graphql.codegen.GetConsignmentStatus.getConsignmentStatus.GetConsignment import org.pac4j.play.scala.SecurityComponents -import play.api.i18n.{I18nSupport, Messages} +import play.api.i18n.{I18nSupport, Lang, MessagesApi} import play.api.mvc.{Action, AnyContent, Request} import services.FileError.SCHEMA_VALIDATION import services.Statuses._ @@ -26,7 +26,8 @@ class DraftMetadataChecksResultsController @Inject() ( val consignmentService: ConsignmentService, val applicationConfig: ApplicationConfig, val consignmentStatusService: ConsignmentStatusService, - val draftMetadataService: DraftMetadataService + val draftMetadataService: DraftMetadataService, + val messages: MessagesApi )(implicit val ec: ExecutionContext) extends TokenSecurity with I18nSupport { @@ -73,18 +74,20 @@ class DraftMetadataChecksResultsController @Inject() ( } } - private def actionMessage(fileError: FileError.FileError)(implicit messages: Messages): String = { + implicit val defaultLang: Lang = Lang.defaultLang + + private def actionMessage(fileError: FileError.FileError): String = { val key = s"draftMetadata.validation.action.$fileError" - if (Messages.isDefinedAt(key)) - Messages(key) + if (messages.isDefinedAt(key)) + messages(key) else s"Require action message for $key" } - private def detailsMessage(fileError: FileError.FileError)(implicit messages: Messages): String = { + private def detailsMessage(fileError: FileError.FileError): String = { val key = s"draftMetadata.validation.details.$fileError" - if (Messages.isDefinedAt(key)) - Messages(key) + if (messages.isDefinedAt(key)) + messages(key) else s"Require details message for $key" } diff --git a/conf/messages b/conf/messages index 9ed9892ce..3818e2e1b 100644 --- a/conf/messages +++ b/conf/messages @@ -38,3 +38,5 @@ notification.savedProgress.metadataInfo=Your records and any metadata you added additionalMetadata.descriptive.sensitive=If the description of a record contains sensitive information, you must enter the full uncensored version on the Descriptive metadata page before entering an alternative description on the Closure metadata page. draftMetadata.validation.details.SCHEMA_VALIDATION=We found validation errors in the uploaded metadata. draftMetadata.validation.action.SCHEMA_VALIDATION=Download the report below for details on individual validation errors. +draftMetadata.validation.details.UTF_8=The metadata file you uploaded was not a CSV. +draftMetadata.validation.action.UTF_8=Ensure that you save your Excel file as file type ''CSV UTF-8 (comma separated)''. diff --git a/test/controllers/DraftMetadataChecksResultsControllerSpec.scala b/test/controllers/DraftMetadataChecksResultsControllerSpec.scala index 9c5cc94b5..e77d31c7d 100644 --- a/test/controllers/DraftMetadataChecksResultsControllerSpec.scala +++ b/test/controllers/DraftMetadataChecksResultsControllerSpec.scala @@ -12,6 +12,7 @@ import org.scalatest.matchers.should.Matchers._ import play.api.Configuration import play.api.Play.materializer import play.api.http.HttpVerbs.GET +import play.api.i18n.DefaultMessagesApi import play.api.test.CSRFTokenHelper._ import play.api.test.FakeRequest import play.api.test.Helpers.{contentAsBytes, contentAsString, defaultAwaitTimeout, status => playStatus, _} @@ -22,9 +23,11 @@ import uk.gov.nationalarchives.tdr.validation.Metadata import java.io.ByteArrayInputStream import java.time.{LocalDateTime, ZoneId, ZonedDateTime} -import java.util.UUID +import java.util.{Properties, UUID} import scala.concurrent.{ExecutionContext, Future} +import scala.io.Source import scala.jdk.CollectionConverters.IterableHasAsScala +import scala.util.Using class DraftMetadataChecksResultsControllerSpec extends FrontEndTestHelper { implicit val ec: ExecutionContext = ExecutionContext.global @@ -117,10 +120,15 @@ class DraftMetadataChecksResultsControllerSpec extends FrontEndTestHelper { "DraftMetadataChecksResultsController should render the error page with error report download button" should { val draftMetadataStatuses = Table( - ("status", "fileError"), - (CompletedWithIssuesValue.value, FileError.SCHEMA_VALIDATION) + ("status", "fileError", "detailsMessage", "actionMessage"), + ( + CompletedWithIssuesValue.value, + FileError.SCHEMA_VALIDATION, + "We found validation errors in the uploaded metadata.", + "Download the report below for details on individual validation errors." + ) ) - forAll(draftMetadataStatuses) { (statusValue, fileError) => + forAll(draftMetadataStatuses) { (statusValue, fileError, detailsMessage, actionMessage) => { s"render the draftMetadataResults page when the status is $statusValue" in { val controller = instantiateController(blockDraftMetadataUpload = false, fileError = fileError) @@ -145,36 +153,8 @@ class DraftMetadataChecksResultsControllerSpec extends FrontEndTestHelper { | Results of your metadata checks |

""".stripMargin ) - pageAsString must include( - s"""
- |
- |
- | Status - |
- |
- | Issues found - |
- |
- | - |
- |
- | Details - |
- |
- | Require details message for draftMetadata.validation.details.$fileError - |
- |
- | - |
- |
- | Action - |
- |
- | Require action message for draftMetadata.validation.action.$fileError - |
- |
- |
""".stripMargin - ) + pageAsString must include(detailsMessage) + pageAsString must include(actionMessage) pageAsString must include("""

The report below contains details about issues found.

""") pageAsString must include( s"""