From a36963d753782ed8ab5f0483954844576c186c97 Mon Sep 17 00:00:00 2001 From: JakeReid2020 <75027964+JakeReid2020@users.noreply.github.com> Date: Mon, 15 Sep 2025 14:59:38 +0100 Subject: [PATCH 01/11] [NGR-1126] WIP --- ...cesOrGaragesIncludedInRentController.scala | 2 +- .../InterimRentSetByTheCourtController.scala | 129 ++++++++++++++++++ .../ngrraldfrontend/models/NGRMonthYear.scala | 61 +++++++++ .../models/forms/CommonFormValidators.scala | 24 ++++ .../forms/InterimRentSetByTheCourtForm.scala | 82 +++++++++++ .../hmrc/ngrraldfrontend/repo/RaldRepo.scala | 7 + .../InterimRentSetByTheCourtView.scala.html | 76 +++++++++++ conf/app.routes | 4 +- conf/messages | 9 +- .../InterimRentSetByTheCourtFormSpec.scala | 3 + 10 files changed, 394 insertions(+), 3 deletions(-) create mode 100644 app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala create mode 100644 app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala create mode 100644 app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala create mode 100644 app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html create mode 100644 test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala diff --git a/app/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentController.scala b/app/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentController.scala index 2a8d9ad6..a3fa14c3 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentController.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentController.scala @@ -16,7 +16,7 @@ package uk.gov.hmrc.ngrraldfrontend.controllers -import play.api.data.{Form, FormError, Forms} +import play.api.data.{Form, FormError} import play.api.i18n.{I18nSupport, Messages} import play.api.mvc.{Action, AnyContent, MessagesControllerComponents} import play.twirl.api.HtmlFormat diff --git a/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala b/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala new file mode 100644 index 00000000..17bcfeec --- /dev/null +++ b/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala @@ -0,0 +1,129 @@ +/* + * Copyright 2025 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.gov.hmrc.ngrraldfrontend.controllers + +import play.api.data.{Form, FormError} +import play.api.i18n.I18nSupport +import play.api.mvc.{Action, AnyContent, MessagesControllerComponents} +import uk.gov.hmrc.ngrraldfrontend.actions.{AuthRetrievals, PropertyLinkingAction} +import uk.gov.hmrc.ngrraldfrontend.config.AppConfig +import uk.gov.hmrc.ngrraldfrontend.repo.RaldRepo +import play.twirl.api.HtmlFormat +import play.api.i18n.{I18nSupport, Messages} +import uk.gov.hmrc.govukfrontend.views.Aliases.{Fieldset, Hint, PrefixOrSuffix, Text} +import uk.gov.hmrc.govukfrontend.views.viewmodels.dateinput.{DateInput, InputItem} +import uk.gov.hmrc.govukfrontend.views.viewmodels.fieldset.{Fieldset, Legend} +import uk.gov.hmrc.http.NotFoundException +import uk.gov.hmrc.ngrraldfrontend.views.html.InterimRentSetByTheCourtView +import uk.gov.hmrc.ngrraldfrontend.models.forms.InterimRentSetByTheCourtForm +import uk.gov.hmrc.ngrraldfrontend.models.forms.InterimRentSetByTheCourtForm.form +import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId + +import uk.gov.hmrc.ngrraldfrontend.views.html.components.{DateTextFields, InputText} +import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendController + +import javax.inject.Inject +import scala.concurrent.{ExecutionContext, Future} + +class InterimRentSetByTheCourtController @Inject()(interimRentSetByTheCourtView: InterimRentSetByTheCourtView, + authenticate: AuthRetrievals, + inputText: InputText, + hasLinkedProperties: PropertyLinkingAction, + raldRepo: RaldRepo, + mcc: MessagesControllerComponents)(implicit appConfig: AppConfig, ec: ExecutionContext) + extends FrontendController(mcc) with I18nSupport { + + def generateDateInput(implicit messages: Messages): DateInput = DateInput( + id = "interimRentSetByTheCourt.date", + namePrefix = Some("interimRentSetByTheCourt.date"), + fieldset = Some(Fieldset( + legend = Some(Legend( + content = Text(messages("interimRentSetByTheCourt.label.2")), + classes = "govuk-fieldset__legend--m", + isPageHeading = true + )) + )), + items = Seq( + InputItem( + id = "interimRentSetByTheCourt.Month", + name = "interimRentSetByTheCourt.Month", + value = form("interimRentSetByTheCourt.month").value, + label = Some("interimRentSetByTheCourt.inputField.month"), + classes = s"govuk-input--width-2".trim + ), + InputItem( + id = "interimRentSetByTheCourt.Year", + name = "interimRentSetByTheCourt.Year", + label = Some("interimRentSetByTheCourt.inputField.year"), + value = form("interimRentSetByTheCourt.year").value, + classes = s"govuk-input--width-2".trim + ) + ), + hint = Some(Hint( + id = Some("interimRentSetByTheCourt.hint.2"), + content = Text(messages("interimRentSetByTheCourt.hint.2")) + )) + ) + + def generateInputText(form: Form[InterimRentSetByTheCourtForm], inputFieldName: String)(implicit messages: Messages): HtmlFormat.Appendable = { + inputText( + form = form, + id = inputFieldName, + name = inputFieldName, + label = messages(s"interimRentSetByTheCourt.$inputFieldName.label"), + headingMessageArgs = Seq("govuk-fieldset__legend govuk-fieldset__legend--s"), + isPageHeading = true, + isVisible = true, + classes = Some("govuk-input govuk-input--width-5"), + prefix = Some(PrefixOrSuffix(content = Text("£"))) + ) + } + + def show: Action[AnyContent] = { + (authenticate andThen hasLinkedProperties).async { implicit request => + request.propertyLinking.map(property => + Future.successful(Ok(interimRentSetByTheCourtView( + form = form, + propertyAddress = property.addressFull, + howMuch = generateInputText(form, "howMuch"), + dateInput = generateDateInput() + )))).getOrElse(throw new NotFoundException("Couldn't find property in mongo")) + } + } + + def submit: Action[AnyContent] = + (authenticate andThen hasLinkedProperties).async { implicit request => + form.bindFromRequest().fold( + formWithErrors => { + request.propertyLinking.map(property => + Future.successful(BadRequest(interimRentSetByTheCourtView( + form = formWithErrors, + propertyAddress = property.addressFull, + howMuch = generateInputText(formWithErrors, "howMuch"), + dateInput = generateDateInput() + )))).getOrElse(throw new NotFoundException("Couldn't find property in mongo")) + }, + interimRent => + raldRepo.insertInterimRentSetByTheCourt( + credId = CredId(request.credId.getOrElse("")), + amount = interimRent.amount, + date = interimRent.date.makeString + ) + Future.successful(Redirect(routes.CheckRentFreePeriodController.show.url)) + ) + } + } diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala new file mode 100644 index 00000000..510fb643 --- /dev/null +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala @@ -0,0 +1,61 @@ +/* + * Copyright 2025 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.gov.hmrc.ngrraldfrontend.models + +import play.api.data.Forms.{mapping, text} +import play.api.data.Mapping +import play.api.libs.json.{Json, OFormat} + +import java.time.LocalDate +import java.time.format.{DateTimeFormatter, TextStyle} +import java.util.Locale + +final case class NGRMonthYear(month: String, year: String) { + def makeString: String = { + val monthStr = f"${month.toInt}%02d" + s"$year-$monthStr" + } +} + +object NGRMonthYear { + implicit val format: OFormat[NGRMonthYear] = Json.format[NGRMonthYear] + + def formatDate(dateString: String): String = { + val date = LocalDate.parse(dateString) + val outputFormatter = DateTimeFormatter.ofPattern("MMMM yyyy", Locale.UK) + date.format(outputFormatter) + } + + + def unapply(ngrMonthYear: NGRMonthYear): Option[(String, String)] = + Some(ngrMonthYear.month, ngrMonthYear.year) +} + +trait MonthYearMappings { + def monthYearMapping: Mapping[NGRMonthYear] = { + mapping( + "month" -> text().transform(_.strip(), identity), + "year" -> text().transform(_.strip(), identity), + )(NGRMonthYear.apply)(NGRMonthYear.unapply) + } +} + +def monthYearErrorKeys(pageName: String, whichDate: String): Map[DateErrorKeys, String] = Map( + Required -> s"$pageName.$whichDate.required.error", + Month -> s"$pageName.$whichDate.month.required.error", + Year -> s"$pageName.$whichDate.year.required.error" +) \ No newline at end of file diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala index 033bb475..28c619db 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala @@ -68,6 +68,17 @@ trait CommonFormValidators { } } + protected def isMonthYearEmpty[A](errorKeys: Map[DateErrorKeys, String]): Constraint[A] = + Constraint((input: A) => + monthYearEmptyValidation(input.asInstanceOf[NGRMonthYear], errorKeys) + ) + + protected def isMonthYearValid[A](errorKey: String): Constraint[A] = + Constraint((input: A) => + val date = input.asInstanceOf[NGRMonthYear] + monthYearValidation(date, errorKey) + ) + protected def isDateEmpty[A](errorKeys: Map[DateErrorKeys, String]): Constraint[A] = Constraint((input: A) => dateEmptyValidation(input.asInstanceOf[NGRDate], errorKeys) @@ -96,6 +107,13 @@ trait CommonFormValidators { case (false, false, true) => Invalid(errorKeys.get(Year).getOrElse("")) case (_, _, _) => Valid + protected def monthYearEmptyValidation(date: NGRMonthYear, errorKeys: Map[DateErrorKeys, String]): ValidationResult = + (date.month.isEmpty, date.year.isEmpty) match + case (true, true) => Invalid(errorKeys.get(Required).getOrElse("")) + case (true, false) => Invalid(errorKeys.get(Month).getOrElse("")) + case (false, true) => Invalid(errorKeys.get(Year).getOrElse("")) + case (false, false) => Valid + protected def dateValidation(date: NGRDate, errorKey: String) = if (Try(date.ngrDate).isFailure || (Try(date.ngrDate).isSuccess && date.year.length > 4)) Invalid(errorKey) @@ -107,4 +125,10 @@ trait CommonFormValidators { Invalid(errorKey) else Valid + + protected def monthYearValidation(date: NGRMonthYear, errorKey: String) = + if (date.month.toInt > 11 || date.month.toInt + date.year.toInt) + Invalid(errorKey) + else + Valid } diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala new file mode 100644 index 00000000..53ffddcc --- /dev/null +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala @@ -0,0 +1,82 @@ +/* + * Copyright 2025 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.gov.hmrc.ngrraldfrontend.models.forms + +import play.api.data.* +import play.api.data.Forms.* +import play.api.data.format.Formatter +import play.api.libs.json.{Json, OFormat} +import uk.gov.hmrc.ngrraldfrontend.models.* + +import scala.util.Try + + +final case class InterimRentSetByTheCourtForm(amount: BigDecimal, date: NGRMonthYear) + +object InterimRentSetByTheCourtForm extends CommonFormValidators with MonthYearMappings { + implicit val format: OFormat[InterimRentSetByTheCourtForm] = Json.format[InterimRentSetByTheCourtForm] + + private lazy val howMuch = "howMuch" + private lazy val howMuchEmptyError = "howMuch.empty.error" + private lazy val howMuchMaxError = "howMuch.tooLarge.error" + private lazy val howMuchFormatError = "howMuch.format.error" + private val dateInput = "interimRentSetByTheCourt.date" + + def unapply(interimRentSetByTheCourtForm: InterimRentSetByTheCourtForm): Option[(BigDecimal, NGRMonthYear)] = Some(interimRentSetByTheCourtForm.amount, interimRentSetByTheCourtForm.date) + + private def errorKeys(whichDate: String): Map[DateErrorKeys, String] = Map( + Required -> s"agreementVerbal.$whichDate.required.error", + MonthAndYear -> s"agreementVerbal.$whichDate.monthAndYear.required.error", + Month -> s"agreementVerbal.$whichDate.month.required.error", + Year -> s"agreementVerbal.$whichDate.year.required.error" + ) + + def bigDecimalWithFormatError: Formatter[BigDecimal] = new Formatter[BigDecimal] { + override def bind(key: String, data: Map[String, String]): Either[Seq[FormError], BigDecimal] = { + data.get(key).filter(_.nonEmpty) match { + case Some(value) => + Try(BigDecimal(value)).toEither.left.map(_ => + Seq(FormError(key, howMuchFormatError)) + ) + case None => + Left(Seq(FormError(key, howMuchEmptyError))) + } + } + override def unbind(key: String, value: BigDecimal): Map[String, String] = + Map(key -> value.toString()) + } + + val annualRentFormMapping: (String, Mapping[BigDecimal]) = + howMuch -> of(bigDecimalWithFormatError) + .verifying(howMuchMaxError, _ <= BigDecimal("9999999.99")) + + val form: Form[InterimRentSetByTheCourtForm] = Form( + mapping( + annualRentFormMapping, + dateInput -> monthYearMapping + .verifying( + firstError( + isMonthYearEmpty(errorKeys("startDate")), + isMonthYearValid("agreement.startDate.format.error") + ) + ), + )(InterimRentSetByTheCourtForm.apply)(InterimRentSetByTheCourtForm.unapply) + ) + +} + + diff --git a/app/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepo.scala b/app/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepo.scala index b2f3f11a..a58bd9a4 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepo.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepo.scala @@ -254,6 +254,13 @@ case class RaldRepo @Inject()(mongo: MongoComponent, findAndUpdateByCredId(credId, updates: _*) } + def insertInterimRentSetByTheCourt(credId: CredId, amount: BigDecimal, date: String) = { + val updates = Seq( + Updates.set("interimRentSetByTheCourt.amount", amount.toString()), + Updates.set("interimRentSetByTheCourt.date", date), + ) + findAndUpdateByCredId(credId, updates: _*) + } def findByCredId(credId: CredId): Future[Option[RaldUserAnswers]] = { collection.find( diff --git a/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html b/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html new file mode 100644 index 00000000..5c479864 --- /dev/null +++ b/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html @@ -0,0 +1,76 @@ +@* + * Copyright 2025 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *@ + +@import uk.gov.hmrc.govukfrontend.views.html.components._ +@import uk.gov.hmrc.govukfrontend.views.Aliases._ +@import uk.gov.hmrc.ngrraldfrontend.views.html.components._ +@import uk.gov.hmrc.ngrraldfrontend.viewmodels.govuk.all._ +@import uk.gov.hmrc.ngrraldfrontend.config.AppConfig +@import uk.gov.hmrc.ngrraldfrontend.models.forms.InterimRentSetByTheCourtForm + +@this( + layout: Layout, + formHelper: FormWithCSRF, + dateInputField: DateTextFields, + govukDateInput: GovukDateInput, + govukErrorSummary: GovukErrorSummary, + saveAndContinueButton: saveAndContinueButton +) + +@(form:Form[InterimRentSetByTheCourtForm], propertyAddress: String, howMuch: Html, dateInput: DateInput)(implicit request: RequestHeader, messages: Messages, appConfig: AppConfig) + +@layout(pageTitle = Some(messages("interimRentSetByTheCourt.title")), showBackLink = true, fullWidth = false) { + @formHelper(action = uk.gov.hmrc.ngrraldfrontend.controllers.routes.InterimRentSetByTheCourtController.submit, Symbol("autoComplete") -> "off") { + @if(form.errors.nonEmpty) { + @govukErrorSummary(ErrorSummaryViewModel(form)) + } + @propertyAddress +

@messages("interimRentSetByTheCourt.title")

+ @howMuch + @govukDateInput(DateInput( + id = "interimRentSetByTheCourt.date", + namePrefix = Some("interimRentSetByTheCourt.date"), + fieldset = Some(Fieldset( + legend = Some(Legend( + content = Text(messages("interimRentSetByTheCourt.label.2")), + classes = "govuk-fieldset__legend--m", + isPageHeading = true + )) + )), + items = Seq( + InputItem( + id = "interimRentSetByTheCourt.Month", + classes = s"govuk-input--width-2", + name = "interimRentSetByTheCourt.Month", + label = Some(messages("interimRentSetByTheCourt.inputField.month")), + value = form("interimRentSetByTheCourt.month").value + ), + InputItem( + id = "interimRentSetByTheCourt.Year", + name = "interimRentSetByTheCourt.Year", + label = Some("interimRentSetByTheCourt.inputField.year"), + value = form("interimRentSetByTheCourt.year").value + ) + ), + hint = Some(Hint( + id = Some("interimRentSetByTheCourt.hint.2"), + content = Text(messages("interimRentSetByTheCourt.hint.2")) + )) + )) + @dateInputField(form, dateInput) + @saveAndContinueButton(msg = messages("service.continue"), isStartButton = false) + } +} \ No newline at end of file diff --git a/conf/app.routes b/conf/app.routes index 9b65aefd..cd354afe 100644 --- a/conf/app.routes +++ b/conf/app.routes @@ -43,4 +43,6 @@ POST /what-rent-includes uk.gov.hmrc.ngrraldf GET /does-rent-include-parking-spaces-or-garages uk.gov.hmrc.ngrraldfrontend.controllers.DoesYourRentIncludeParkingController.show POST /does-rent-include-parking-spaces-or-garages uk.gov.hmrc.ngrraldfrontend.controllers.DoesYourRentIncludeParkingController.submit GET /how-many-parking-spaces-or-garages-included-in-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowManyParkingSpacesOrGaragesIncludedInRentController.show -POST /how-many-parking-spaces-or-garages-included-in-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowManyParkingSpacesOrGaragesIncludedInRentController.submit \ No newline at end of file +POST /how-many-parking-spaces-or-garages-included-in-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowManyParkingSpacesOrGaragesIncludedInRentController.submit +GET /interim-rent-set-by-court uk.gov.hmrc.ngrraldfrontend.controllers.InterimRentSetByTheCourtController.show +POST /interim-rent-set-by-court uk.gov.hmrc.ngrraldfrontend.controllers.InterimRentSetByTheCourtController.submit \ No newline at end of file diff --git a/conf/messages b/conf/messages index 456567b9..661020c5 100644 --- a/conf/messages +++ b/conf/messages @@ -343,7 +343,6 @@ howManyParkingSpacesOrGaragesIncludedInRent.hint = If spaces are in communal car howManyParkingSpacesOrGaragesIncludedInRent.uncoveredSpaces.label = Uncovered spaces howManyParkingSpacesOrGaragesIncludedInRent.coveredSpaces.label = Covered spaces howManyParkingSpacesOrGaragesIncludedInRent.garages.label = Garages - howManyParkingSpacesOrGaragesIncludedInRent.error.required = Total number of uncovered spaces, covered spaces and garages included in your rent must be more than 0 howManyParkingSpacesOrGaragesIncludedInRent.allFields.error.required = Enter how many parking spaces or garages are included in your rent howManyParkingSpacesOrGaragesIncludedInRent.uncoveredSpaces.wholeNum.error = Number of uncovered parking spaces included in your rent must be a number, like 9 @@ -352,3 +351,11 @@ howManyParkingSpacesOrGaragesIncludedInRent.garages.wholeNum.error = Number of g howManyParkingSpacesOrGaragesIncludedInRent.uncoveredSpaces.tooHigh.error = Number of uncovered parking spaces included in your rent must be 9,999 or less howManyParkingSpacesOrGaragesIncludedInRent.coveredSpaces.tooHigh.error = Number of covered parking spaces included in your rent must be 9,999 or less howManyParkingSpacesOrGaragesIncludedInRent.garages.tooHigh.error = Number of garages included in your rent must be 9,999 or less + +#InterimRentSetByTheCourt +interimRentSetByTheCourt.title = Interim rent set by the court +interimRentSetByTheCourt.label.1 = How much was the interim rent? +interimRentSetByTheCourt.label.2 = When did you start paying the interim rent? +interimRentSetByTheCourt.hint.2 = For example, 6 2026 +interimRentSetByTheCourt.inputField.month = Month +interimRentSetByTheCourt.inputField.year = Year diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala new file mode 100644 index 00000000..4d487669 --- /dev/null +++ b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala @@ -0,0 +1,3 @@ +package uk.gov.hmrc.ngrraldfrontend.models.forms + +class InterimRentSetByTheCourtFormSpec From debb3d976cfb2e92a3178ddca2f661999c3540b0 Mon Sep 17 00:00:00 2001 From: JakeReid2020 <75027964+JakeReid2020@users.noreply.github.com> Date: Tue, 16 Sep 2025 15:31:42 +0100 Subject: [PATCH 02/11] [NGR-1126] Adding all tests --- .../InterimRentSetByTheCourtController.scala | 42 +--- .../controllers/RentInterimController.scala | 2 +- .../ngrraldfrontend/models/NGRMonthYear.scala | 7 +- .../models/forms/CommonFormValidators.scala | 37 +++- .../forms/InterimRentSetByTheCourtForm.scala | 25 +-- .../InterimRentSetByTheCourtView.scala.html | 40 +--- .../InputDateForMonthYear.scala.html | 70 +++++++ conf/messages | 13 +- ...terimRentSetByTheCourtControllerSpec.scala | 140 +++++++++++++ .../RentInterimControllerSpec.scala | 2 +- .../InterimRentSetByTheCourtFormSpec.scala | 195 +++++++++++++++++- .../InterimRentSetByTheCourtViewSpec.scala | 94 +++++++++ 12 files changed, 569 insertions(+), 98 deletions(-) create mode 100644 app/uk/gov/hmrc/ngrraldfrontend/views/components/InputDateForMonthYear.scala.html create mode 100644 test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala create mode 100644 test/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtViewSpec.scala diff --git a/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala b/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala index 17bcfeec..34b6f437 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala @@ -41,50 +41,18 @@ import scala.concurrent.{ExecutionContext, Future} class InterimRentSetByTheCourtController @Inject()(interimRentSetByTheCourtView: InterimRentSetByTheCourtView, authenticate: AuthRetrievals, - inputText: InputText, hasLinkedProperties: PropertyLinkingAction, + inputText: InputText, raldRepo: RaldRepo, mcc: MessagesControllerComponents)(implicit appConfig: AppConfig, ec: ExecutionContext) extends FrontendController(mcc) with I18nSupport { - - def generateDateInput(implicit messages: Messages): DateInput = DateInput( - id = "interimRentSetByTheCourt.date", - namePrefix = Some("interimRentSetByTheCourt.date"), - fieldset = Some(Fieldset( - legend = Some(Legend( - content = Text(messages("interimRentSetByTheCourt.label.2")), - classes = "govuk-fieldset__legend--m", - isPageHeading = true - )) - )), - items = Seq( - InputItem( - id = "interimRentSetByTheCourt.Month", - name = "interimRentSetByTheCourt.Month", - value = form("interimRentSetByTheCourt.month").value, - label = Some("interimRentSetByTheCourt.inputField.month"), - classes = s"govuk-input--width-2".trim - ), - InputItem( - id = "interimRentSetByTheCourt.Year", - name = "interimRentSetByTheCourt.Year", - label = Some("interimRentSetByTheCourt.inputField.year"), - value = form("interimRentSetByTheCourt.year").value, - classes = s"govuk-input--width-2".trim - ) - ), - hint = Some(Hint( - id = Some("interimRentSetByTheCourt.hint.2"), - content = Text(messages("interimRentSetByTheCourt.hint.2")) - )) - ) def generateInputText(form: Form[InterimRentSetByTheCourtForm], inputFieldName: String)(implicit messages: Messages): HtmlFormat.Appendable = { inputText( form = form, id = inputFieldName, name = inputFieldName, - label = messages(s"interimRentSetByTheCourt.$inputFieldName.label"), + label = messages(s"interimRentSetByTheCourt.label.1"), headingMessageArgs = Seq("govuk-fieldset__legend govuk-fieldset__legend--s"), isPageHeading = true, isVisible = true, @@ -99,8 +67,7 @@ class InterimRentSetByTheCourtController @Inject()(interimRentSetByTheCourtView: Future.successful(Ok(interimRentSetByTheCourtView( form = form, propertyAddress = property.addressFull, - howMuch = generateInputText(form, "howMuch"), - dateInput = generateDateInput() + howMuch = generateInputText(form, "howMuch") )))).getOrElse(throw new NotFoundException("Couldn't find property in mongo")) } } @@ -113,8 +80,7 @@ class InterimRentSetByTheCourtController @Inject()(interimRentSetByTheCourtView: Future.successful(BadRequest(interimRentSetByTheCourtView( form = formWithErrors, propertyAddress = property.addressFull, - howMuch = generateInputText(formWithErrors, "howMuch"), - dateInput = generateDateInput() + howMuch = generateInputText(formWithErrors, "howMuch") )))).getOrElse(throw new NotFoundException("Couldn't find property in mongo")) }, interimRent => diff --git a/app/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimController.scala b/app/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimController.scala index e3d64b64..f5110a62 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimController.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimController.scala @@ -68,7 +68,7 @@ class RentInterimController @Inject()(rentInterimView: RentInterimView, agreedRentChange = radioValue.radioValue ) if (radioValue.radioValue == "Yes") { - Future.successful(Redirect(routes.ProvideDetailsOfFirstSecondRentPeriodController.show.url)) + Future.successful(Redirect(routes.InterimRentSetByTheCourtController.show.url)) } else { Future.successful(Redirect(routes.CheckRentFreePeriodController.show.url)) } diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala index 510fb643..c3703cc0 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala @@ -26,7 +26,8 @@ import java.util.Locale final case class NGRMonthYear(month: String, year: String) { def makeString: String = { - val monthStr = f"${month.toInt}%02d" + println(Console.MAGENTA_B + month.toIntOption.getOrElse(0) + Console.RESET ) + val monthStr = f"${month.toIntOption.getOrElse(0)}%02d" s"$year-$monthStr" } } @@ -55,7 +56,5 @@ trait MonthYearMappings { } def monthYearErrorKeys(pageName: String, whichDate: String): Map[DateErrorKeys, String] = Map( - Required -> s"$pageName.$whichDate.required.error", - Month -> s"$pageName.$whichDate.month.required.error", - Year -> s"$pageName.$whichDate.year.required.error" + Required -> s"$pageName.$whichDate.required.error" ) \ No newline at end of file diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala index 28c619db..4cbe4c12 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala @@ -79,6 +79,12 @@ trait CommonFormValidators { monthYearValidation(date, errorKey) ) + protected def isMonthYearAfter1900[A](errorKey: String): Constraint[A] = + Constraint((input: A) => + val date = input.asInstanceOf[NGRMonthYear] + monthYearAfter1900Validation(date, errorKey) + ) + protected def isDateEmpty[A](errorKeys: Map[DateErrorKeys, String]): Constraint[A] = Constraint((input: A) => dateEmptyValidation(input.asInstanceOf[NGRDate], errorKeys) @@ -112,23 +118,40 @@ trait CommonFormValidators { case (true, true) => Invalid(errorKeys.get(Required).getOrElse("")) case (true, false) => Invalid(errorKeys.get(Month).getOrElse("")) case (false, true) => Invalid(errorKeys.get(Year).getOrElse("")) - case (false, false) => Valid + case (_, _) => Valid protected def dateValidation(date: NGRDate, errorKey: String) = if (Try(date.ngrDate).isFailure || (Try(date.ngrDate).isSuccess && date.year.length > 4)) Invalid(errorKey) else Valid - + + + private def monthYearAfter1900Validation(date: NGRMonthYear, errorKey: String) = + val maybeYear = date.year.toIntOption + maybeYear match { + case Some(year) => + if (date.year.toInt < 1900) + Invalid (errorKey) + else + Valid + case None => Invalid(errorKey) + } + private def dateAfter1900Validation(date: NGRDate, errorKey: String) = if (Try(date.ngrDate).isSuccess && date.year.toInt < 1900) Invalid(errorKey) else Valid - protected def monthYearValidation(date: NGRMonthYear, errorKey: String) = - if (date.month.toInt > 11 || date.month.toInt + date.year.toInt) - Invalid(errorKey) - else - Valid + protected def monthYearValidation(date: NGRMonthYear, errorKey: String) = { + val maybeMonth = date.month.toIntOption + val maybeYear = date.year.toIntOption + (maybeMonth, maybeYear) match { + case (Some(month), Some(year)) if month >= 0 && month <= 12 && (month + year != 0) => + Valid + case _ => + Invalid(errorKey) + } + } } diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala index 53ffddcc..f19e8423 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala @@ -20,7 +20,8 @@ import play.api.data.* import play.api.data.Forms.* import play.api.data.format.Formatter import play.api.libs.json.{Json, OFormat} -import uk.gov.hmrc.ngrraldfrontend.models.* +import uk.gov.hmrc.ngrraldfrontend.models.forms.ProvideDetailsOfFirstSecondRentPeriodForm.isDateAfter1900 +import uk.gov.hmrc.ngrraldfrontend.models.{Month, *} import scala.util.Try @@ -31,18 +32,17 @@ object InterimRentSetByTheCourtForm extends CommonFormValidators with MonthYearM implicit val format: OFormat[InterimRentSetByTheCourtForm] = Json.format[InterimRentSetByTheCourtForm] private lazy val howMuch = "howMuch" - private lazy val howMuchEmptyError = "howMuch.empty.error" - private lazy val howMuchMaxError = "howMuch.tooLarge.error" - private lazy val howMuchFormatError = "howMuch.format.error" - private val dateInput = "interimRentSetByTheCourt.date" + private lazy val howMuchEmptyError = "interimRentSetByTheCourt.howMany.required.error" + private lazy val howMuchMaxError = "interimRentSetByTheCourt.howMany.tooLarge.error" + private lazy val howMuchFormatError = "interimRentSetByTheCourt.howMany.format.error" + private val dateInput = "date" def unapply(interimRentSetByTheCourtForm: InterimRentSetByTheCourtForm): Option[(BigDecimal, NGRMonthYear)] = Some(interimRentSetByTheCourtForm.amount, interimRentSetByTheCourtForm.date) private def errorKeys(whichDate: String): Map[DateErrorKeys, String] = Map( - Required -> s"agreementVerbal.$whichDate.required.error", - MonthAndYear -> s"agreementVerbal.$whichDate.monthAndYear.required.error", - Month -> s"agreementVerbal.$whichDate.month.required.error", - Year -> s"agreementVerbal.$whichDate.year.required.error" + Required -> s"$whichDate.required.error", + Month -> s"$whichDate.month.required.error", + Year -> s"$whichDate.year.required.error" ) def bigDecimalWithFormatError: Formatter[BigDecimal] = new Formatter[BigDecimal] { @@ -67,11 +67,12 @@ object InterimRentSetByTheCourtForm extends CommonFormValidators with MonthYearM val form: Form[InterimRentSetByTheCourtForm] = Form( mapping( annualRentFormMapping, - dateInput -> monthYearMapping + "date" -> monthYearMapping .verifying( firstError( - isMonthYearEmpty(errorKeys("startDate")), - isMonthYearValid("agreement.startDate.format.error") + isMonthYearEmpty(errorKeys("interimRentSetByTheCourt")), + isMonthYearValid("interimRentSetByTheCourt.monthYear.format.error"), + isMonthYearAfter1900("interimRentSetByTheCourt.startDate.before.1900.error") ) ), )(InterimRentSetByTheCourtForm.apply)(InterimRentSetByTheCourtForm.unapply) diff --git a/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html b/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html index 5c479864..6ee888c4 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html +++ b/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html @@ -25,12 +25,13 @@ layout: Layout, formHelper: FormWithCSRF, dateInputField: DateTextFields, + inputDateForMonthYear: components.InputDateForMonthYear, govukDateInput: GovukDateInput, govukErrorSummary: GovukErrorSummary, saveAndContinueButton: saveAndContinueButton ) -@(form:Form[InterimRentSetByTheCourtForm], propertyAddress: String, howMuch: Html, dateInput: DateInput)(implicit request: RequestHeader, messages: Messages, appConfig: AppConfig) +@(form:Form[InterimRentSetByTheCourtForm], propertyAddress: String, howMuch: Html)(implicit request: RequestHeader, messages: Messages, appConfig: AppConfig) @layout(pageTitle = Some(messages("interimRentSetByTheCourt.title")), showBackLink = true, fullWidth = false) { @formHelper(action = uk.gov.hmrc.ngrraldfrontend.controllers.routes.InterimRentSetByTheCourtController.submit, Symbol("autoComplete") -> "off") { @@ -40,37 +41,12 @@ @propertyAddress

@messages("interimRentSetByTheCourt.title")

@howMuch - @govukDateInput(DateInput( - id = "interimRentSetByTheCourt.date", - namePrefix = Some("interimRentSetByTheCourt.date"), - fieldset = Some(Fieldset( - legend = Some(Legend( - content = Text(messages("interimRentSetByTheCourt.label.2")), - classes = "govuk-fieldset__legend--m", - isPageHeading = true - )) - )), - items = Seq( - InputItem( - id = "interimRentSetByTheCourt.Month", - classes = s"govuk-input--width-2", - name = "interimRentSetByTheCourt.Month", - label = Some(messages("interimRentSetByTheCourt.inputField.month")), - value = form("interimRentSetByTheCourt.month").value - ), - InputItem( - id = "interimRentSetByTheCourt.Year", - name = "interimRentSetByTheCourt.Year", - label = Some("interimRentSetByTheCourt.inputField.year"), - value = form("interimRentSetByTheCourt.year").value - ) - ), - hint = Some(Hint( - id = Some("interimRentSetByTheCourt.hint.2"), - content = Text(messages("interimRentSetByTheCourt.hint.2")) - )) - )) - @dateInputField(form, dateInput) + @inputDateForMonthYear( + form, + legendContent = messages("interimRentSetByTheCourt.label.2"), + legendAsPageHeading = false, + hintText = Some(messages("interimRentSetByTheCourt.hint.2")) + ) @saveAndContinueButton(msg = messages("service.continue"), isStartButton = false) } } \ No newline at end of file diff --git a/app/uk/gov/hmrc/ngrraldfrontend/views/components/InputDateForMonthYear.scala.html b/app/uk/gov/hmrc/ngrraldfrontend/views/components/InputDateForMonthYear.scala.html new file mode 100644 index 00000000..33e5af54 --- /dev/null +++ b/app/uk/gov/hmrc/ngrraldfrontend/views/components/InputDateForMonthYear.scala.html @@ -0,0 +1,70 @@ +@* + * Copyright 2025 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *@ + +@import uk.gov.hmrc.govukfrontend.views.html.components._ + +@this(govukDateInput: GovukDateInput) + +@( + form: Form[_], + legendContent: String, + legendClasses: String = "govuk-fieldset__legend--xl", + id: String = "date", + hintText: Option[String] = None, + legendAsPageHeading: Boolean = true)(implicit messages: Messages) + +@govukDateInput(DateInput( + fieldset = Some(Fieldset( + legend = Some( + Legend( + content = Text(messages(legendContent)), + isPageHeading = legendAsPageHeading, + classes = if(legendAsPageHeading){legendClasses}else{"govuk-fieldset__legend--m"} + ) + ) + )), + id = id, + items = Seq( + InputItem( + id = s"$id.month", + classes = s"govuk-input--width-2${if( + form(s"$id.month").hasErrors + || form.errors.exists(_.key.contains("date")) + || form.errors.exists(_.args.contains("month")))" govuk-input--error" else ""}", + name = s"$id.month", + label = Some(messages("date.month")), + value = form(s"$id.month").value + ), + InputItem( + id = s"$id.year", + classes = s"govuk-input--width-4${if( + form(s"$id.year").hasErrors + || form.errors.exists(_.key.contains("date")) + || form.errors.exists(_.args.contains("year")))" govuk-input--error" else ""}", + name = s"$id.year", + label = Some(messages("date.year")), + value = form(s"$id.year").value + ) + ), + hint = hintText.map(hint => Hint(content = Text(messages(hint)))), + errorMessage = form.errors.find(err => + err.key == id || err.key == s"$id.month" || err.key == s"$id.year" || err.key == "date" + ).map { err => + ErrorMessage.errorMessageWithDefaultStringsTranslated( + content = Text(messages(err.message, err.args: _*)) + ) + } +)) \ No newline at end of file diff --git a/conf/messages b/conf/messages index 661020c5..73707a72 100644 --- a/conf/messages +++ b/conf/messages @@ -357,5 +357,14 @@ interimRentSetByTheCourt.title = Interim rent set by the court interimRentSetByTheCourt.label.1 = How much was the interim rent? interimRentSetByTheCourt.label.2 = When did you start paying the interim rent? interimRentSetByTheCourt.hint.2 = For example, 6 2026 -interimRentSetByTheCourt.inputField.month = Month -interimRentSetByTheCourt.inputField.year = Year +date.month = Month +date.year = Year + +interimRentSetByTheCourt.howMany.required.error = Enter how much the interim rent was, in pounds +interimRentSetByTheCourt.howMany.tooLarge.error = Interim rent must be £9,999,999.99 or less +interimRentSetByTheCourt.howMany.format.error = Interim rent must be a number, like 50,000 +interimRentSetByTheCourt.monthYear.format.error = Date your interim rent started must be a real date +interimRentSetByTheCourt.required.error = Enter the date you started paying interim rent +interimRentSetByTheCourt.month.required.error = Date you started paying the interim rent must include a month +interimRentSetByTheCourt.year.required.error = Date you started paying the interim rent must include a year +interimRentSetByTheCourt.startDate.before.1900.error = The date you started paying interim rent must be 1900 or after \ No newline at end of file diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala new file mode 100644 index 00000000..c1ed8b98 --- /dev/null +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala @@ -0,0 +1,140 @@ +/* + * Copyright 2025 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.gov.hmrc.ngrraldfrontend.controllers + + + +/* + * Copyright 2025 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +import play.api.http.Status.{BAD_REQUEST, OK, SEE_OTHER} +import play.api.test.FakeRequest +import play.api.test.Helpers.{await, contentAsString, defaultAwaitTimeout, redirectLocation, status} +import uk.gov.hmrc.http.{HeaderNames, NotFoundException} +import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport +import uk.gov.hmrc.ngrraldfrontend.views.html.InterimRentSetByTheCourtView +import uk.gov.hmrc.ngrraldfrontend.views.html.components.InputText + +class InterimRentSetByTheCourtControllerSpec extends ControllerSpecSupport { + val pageTitle = "Interim rent set by the court" + val view: InterimRentSetByTheCourtView = inject[InterimRentSetByTheCourtView] + val mockInputText: InputText = inject[InputText] + val controller: InterimRentSetByTheCourtController = new InterimRentSetByTheCourtController( + interimRentSetByTheCourtView = view, + authenticate = mockAuthJourney, + hasLinkedProperties = mockPropertyLinkingAction, + inputText = mockInputText, + raldRepo = mockRaldRepo, + mcc = mcc)(mockConfig) + + "InterimRentSetByTheCourtController" must { + "method show" must { + "Return OK and the correct view" in { + val result = controller.show()(authenticatedFakeRequest()) + status(result) mustBe OK + val content = contentAsString(result) + content must include(pageTitle) + } + "Return NotFoundException when property is not found in the mongo" in { + mockRequestWithoutProperty() + val exception = intercept[NotFoundException] { + await(controller.show(authenticatedFakeRequest())) + } + exception.getMessage contains "Couldn't find property in mongo" mustBe true + } + } + + "method submit" must { + "Return OK and the correct view" in { + val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit) + .withFormUrlEncodedBody( + "howMuch" -> "10000", + "date.month" -> "1", + "date.year" -> "1990" + ) + .withHeaders(HeaderNames.authorisation -> "Bearer 1") + + val result = controller.submit()(authenticatedFakeRequest(fakePostRequest)) + status(result) mustBe SEE_OTHER + redirectLocation(result) mustBe Some(routes.CheckRentFreePeriodController.show.url) + } + "Return BAD_REQUEST for missing how much input and the correct view" in { + mockRequest() + val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit) + .withFormUrlEncodedBody( + "howMuch" -> "", + "date.month" -> "1", + "date.year" -> "1990" + ) + .withHeaders(HeaderNames.authorisation -> "Bearer 1") + + val result = controller.submit()(authenticatedFakeRequest(fakePostRequest)) + status(result) mustBe BAD_REQUEST + } + "Return BAD_REQUEST for missing month input and the correct view" in { + mockRequest() + val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit) + .withFormUrlEncodedBody( + "howMuch" -> "1000", + "date.month" -> "", + "date.year" -> "1990" + ) + .withHeaders(HeaderNames.authorisation -> "Bearer 1") + + val result = controller.submit()(authenticatedFakeRequest(fakePostRequest)) + status(result) mustBe BAD_REQUEST + } + "Return BAD_REQUEST for missing year input and the correct view" in { + mockRequest() + val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit) + .withFormUrlEncodedBody( + "howMuch" -> "1000", + "date.month" -> "1", + "date.year" -> "" + ) + .withHeaders(HeaderNames.authorisation -> "Bearer 1") + + val result = controller.submit()(authenticatedFakeRequest(fakePostRequest)) + status(result) mustBe BAD_REQUEST + } + "Return Exception if no address is in the mongo" in { + mockRequestWithoutProperty() + val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit) + .withFormUrlEncodedBody(("how–much–is–total–annual–rent-value", "")) + .withHeaders(HeaderNames.authorisation -> "Bearer 1") + val exception = intercept[NotFoundException] { + await(controller.submit()(authenticatedFakeRequest(fakePostRequest))) + } + exception.getMessage contains "Couldn't find property in mongo" mustBe true + } + } + } +} diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimControllerSpec.scala index 23d682e8..50d05066 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentInterimControllerSpec.scala @@ -53,7 +53,7 @@ class RentInterimControllerSpec extends ControllerSpecSupport { val result = controller.submit()(authenticatedFakeRequest(fakePostRequest)) status(result) mustBe SEE_OTHER - redirectLocation(result) mustBe Some(routes.ProvideDetailsOfFirstSecondRentPeriodController.show.url) + redirectLocation(result) mustBe Some(routes.InterimRentSetByTheCourtController.show.url) } "Return OK and the correct view when no is selected" in { val fakePostRequest = FakeRequest(routes.WhatTypeOfLeaseRenewalController.submit) diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala index 4d487669..8087421a 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala @@ -1,3 +1,196 @@ +/* + * Copyright 2025 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package uk.gov.hmrc.ngrraldfrontend.models.forms -class InterimRentSetByTheCourtFormSpec +import org.scalatest.matchers.should.Matchers +import org.scalatest.matchers.should.Matchers.{should, shouldBe} +import org.scalatest.wordspec.AnyWordSpec +import play.api.data.FormError +import play.api.libs.json.Json +import uk.gov.hmrc.ngrraldfrontend.models.NGRMonthYear + +class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers { + + "InterimRentSetByTheCourtForm" should { + + "bind valid input" in { + val data = Map( + "howMuch" -> "123456.78", + "date.month" -> "1", + "date.year" -> "1990" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.hasErrors shouldBe false + boundForm.value shouldBe Some(InterimRentSetByTheCourtForm( + amount = BigDecimal("123456.78"), + date = NGRMonthYear(month = "1", year = "1990") + )) + } + + "fail to bind empty input" in { + val data = Map.empty[String, String] + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.hasErrors shouldBe true + boundForm.errors should contain(FormError("howMuch", "interimRentSetByTheCourt.howMany.required.error")) + } + + "fail to bind non-numeric input for how much input field" in { + val data = Map( + "howMuch" -> "hello", + "date.month" -> "1", + "date.year" -> "1990" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.errors should contain(FormError("howMuch", "interimRentSetByTheCourt.howMany.format.error")) + } + + "fail to bind input greater than 9999999.99 for how much input field" in { + val data = Map( + "howMuch" -> "123456789.78", + "date.month" -> "1", + "date.year" -> "1990" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.errors should contain(FormError("howMuch", "interimRentSetByTheCourt.howMany.tooLarge.error")) + } + + "bind edge case of exactly 9999999.99" in { + val data = Map( + "howMuch" -> "9999999.99", + "date.month" -> "1", + "date.year" -> "1990" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.hasErrors shouldBe false + boundForm.value shouldBe Some(InterimRentSetByTheCourtForm( + amount = BigDecimal("9999999.99"), + date = NGRMonthYear(month = "1", year = "1990") + )) + } + + "fail to bind incorrect month for month input field" in { + val data = Map( + "howMuch" -> "123456.78", + "date.month" -> "13", + "date.year" -> "1990" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.errors should contain(FormError("date", "interimRentSetByTheCourt.monthYear.format.error")) + } + "fail to bind year before 1900 for year input field" in { + val data = Map( + "howMuch" -> "123456.78", + "date.month" -> "10", + "date.year" -> "1899" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.errors should contain(FormError("date", "interimRentSetByTheCourt.startDate.before.1900.error")) + } + + "fail to bind missing month input" in { + val data = Map( + "howMuch" -> "123456.78", + "date.month" -> "", + "date.year" -> "1899" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.errors should contain(FormError("date", "interimRentSetByTheCourt.month.required.error")) + } + + "fail to bind missing year input" in { + val data = Map( + "howMuch" -> "123456.78", + "date.month" -> "1", + "date.year" -> "" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.errors should contain(FormError("date", "interimRentSetByTheCourt.year.required.error")) + } + + "fail to bind non numeric format for month input" in { + val data = Map( + "howMuch" -> "123456.78", + "date.month" -> "hello", + "date.year" -> "1999" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.errors should contain(FormError("date", "interimRentSetByTheCourt.monthYear.format.error")) + } + + "fail to bind non numeric format for year input" in { + val data = Map( + "howMuch" -> "123456.78", + "date.month" -> "1", + "date.year" -> "hello" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.errors should contain(FormError("date", "interimRentSetByTheCourt.monthYear.format.error")) + } + + } + + "serialize to JSON correctly" in { + val form = InterimRentSetByTheCourtForm( + amount = BigDecimal("9999999.99"), + date = NGRMonthYear(month = "1", year = "1990") + ) + val json = Json.toJson(form) + + json shouldBe Json.obj( + "amount" -> 9999999.99, + "date" -> Json.obj( + "month" -> "1", + "year" -> "1990" + ) + ) + } + + "deserialize from JSON correctly" in { + val json = Json.obj( + "amount" -> 9999999.99, + "date" -> Json.obj( + "month" -> "1", + "year" -> "1990" + ) + ) + val result = json.validate[InterimRentSetByTheCourtForm] + + result.isSuccess shouldBe true + result.get shouldBe InterimRentSetByTheCourtForm( + amount = BigDecimal(9999999.99), + date = NGRMonthYear(month = "1", year = "1990") + ) + } + + "fail deserialization if value is missing" in { + val json = Json.obj() + val result = json.validate[InterimRentSetByTheCourtForm] + + result.isError shouldBe true + } +} \ No newline at end of file diff --git a/test/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtViewSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtViewSpec.scala new file mode 100644 index 00000000..e49668af --- /dev/null +++ b/test/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtViewSpec.scala @@ -0,0 +1,94 @@ +package uk.gov.hmrc.ngrraldfrontend.views + +import org.jsoup.Jsoup +import org.jsoup.nodes.Document +import play.api.data.Form +import play.api.i18n.Messages +import play.twirl.api.HtmlFormat +import uk.gov.hmrc.govukfrontend.views.Aliases.{PrefixOrSuffix, Text} +import uk.gov.hmrc.ngrraldfrontend.helpers.ViewBaseSpec +import uk.gov.hmrc.ngrraldfrontend.models.NGRMonthYear +import uk.gov.hmrc.ngrraldfrontend.models.forms.InterimRentSetByTheCourtForm +import uk.gov.hmrc.ngrraldfrontend.views.html.InterimRentSetByTheCourtView +import uk.gov.hmrc.ngrraldfrontend.views.html.components.InputText + +class InterimRentSetByTheCourtViewSpec extends ViewBaseSpec { + lazy val view: InterimRentSetByTheCourtView = inject[InterimRentSetByTheCourtView] + + object Strings { + val heading = "Interim rent set by the court" + val label1 = "How much was the interim rent?" + val label2 = "When did you start paying the interim rent?" + val hint2 = "For example, 6 2026" + val saveAndContinue = "Continue" + } + + object Selectors { + val heading = "#main-content > div > div.govuk-grid-column-two-thirds > form > h1" + val label1 = "#main-content > div > div.govuk-grid-column-two-thirds > form > div:nth-child(4) > h1 > label" + val label2 = "#main-content > div > div.govuk-grid-column-two-thirds > form > div:nth-child(5) > fieldset > legend" + val hint2 = "#date-hint" + val saveAndContinue = "#continue" + } + + val address = "5 Brixham Marina, Berry Head Road, Brixham, Devon, TQ5 9BW" + + val form = InterimRentSetByTheCourtForm.form.fillAndValidate(InterimRentSetByTheCourtForm(amount = BigDecimal(1000), date = NGRMonthYear(month = "1", year = "2020"))) + val mockInputText: InputText = inject[InputText] + def generateInputText(form: Form[InterimRentSetByTheCourtForm], inputFieldName: String)(implicit messages: Messages): HtmlFormat.Appendable = { + mockInputText( + form = form, + id = inputFieldName, + name = inputFieldName, + label = messages(s"interimRentSetByTheCourt.label.1"), + headingMessageArgs = Seq("govuk-fieldset__legend govuk-fieldset__legend--s"), + isPageHeading = true, + isVisible = true, + classes = Some("govuk-input govuk-input--width-5"), + prefix = Some(PrefixOrSuffix(content = Text("£"))) + ) + } + + val howMuch: HtmlFormat.Appendable = generateInputText(form, "howMuch") + + "InterimRentSetByTheCourtView" must { + val interimRentSetByTheCourtView = view(form, address, howMuch) + lazy implicit val document: Document = Jsoup.parse(interimRentSetByTheCourtView.body) + val htmlApply = view.apply(form, address, howMuch).body + val htmlRender = view.render(form, address, howMuch, request, messages, mockConfig).body + lazy val htmlF = view.f(form, address, howMuch) + + "htmlF is not empty" in { + htmlF.toString() must not be empty + } + + "apply must be the same as render" in { + htmlApply mustBe htmlRender + } + + "render is not empty" in { + htmlRender must not be empty + } + + "show correct heading" in { + elementText(Selectors.heading) mustBe Strings.heading + } + + "show correct label for how much field" in { + elementText(Selectors.label1) mustBe Strings.label1 + } + + "show correct label for month and year fields" in { + elementText(Selectors.label2) mustBe Strings.label2 + } + + "show correct hint for the month and year fields" in { + elementText(Selectors.hint2) mustBe Strings.hint2 + } + + "show correct continue button" in { + elementText(Selectors.saveAndContinue) mustBe Strings.saveAndContinue + } + } +} + From 8f1e68adef6d12fc214c5f42369dc4aa95c0bb0f Mon Sep 17 00:00:00 2001 From: JakeReid2020 <75027964+JakeReid2020@users.noreply.github.com> Date: Wed, 17 Sep 2025 09:01:15 +0100 Subject: [PATCH 03/11] [NGR-1126] Adding all the tests --- .../InterimRentSetByTheCourtViewSpec.scala | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/test/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtViewSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtViewSpec.scala index e49668af..a29c106d 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtViewSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtViewSpec.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2025 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package uk.gov.hmrc.ngrraldfrontend.views import org.jsoup.Jsoup @@ -25,8 +41,8 @@ class InterimRentSetByTheCourtViewSpec extends ViewBaseSpec { object Selectors { val heading = "#main-content > div > div.govuk-grid-column-two-thirds > form > h1" - val label1 = "#main-content > div > div.govuk-grid-column-two-thirds > form > div:nth-child(4) > h1 > label" - val label2 = "#main-content > div > div.govuk-grid-column-two-thirds > form > div:nth-child(5) > fieldset > legend" + val label1 = "#main-content > div > div.govuk-grid-column-two-thirds > form > div:nth-child(3) > h1" + val label2 = "#main-content > div > div.govuk-grid-column-two-thirds > form > div:nth-child(4) > fieldset > legend" val hint2 = "#date-hint" val saveAndContinue = "#continue" } From 1bc18f7ee97c5e675dbb9a21b8ac17bf404ef8da Mon Sep 17 00:00:00 2001 From: JakeReid2020 <75027964+JakeReid2020@users.noreply.github.com> Date: Wed, 17 Sep 2025 09:22:44 +0100 Subject: [PATCH 04/11] [NGR-1126] Fixing hyperlinks --- .../InterimRentSetByTheCourtController.scala | 37 ++++++++++++------- .../forms/InterimRentSetByTheCourtForm.scala | 3 +- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala b/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala index 34b6f437..8a0a7097 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala @@ -16,24 +16,20 @@ package uk.gov.hmrc.ngrraldfrontend.controllers -import play.api.data.{Form, FormError} -import play.api.i18n.I18nSupport +import play.api.data.Form +import play.api.i18n.{I18nSupport, Messages} import play.api.mvc.{Action, AnyContent, MessagesControllerComponents} -import uk.gov.hmrc.ngrraldfrontend.actions.{AuthRetrievals, PropertyLinkingAction} -import uk.gov.hmrc.ngrraldfrontend.config.AppConfig -import uk.gov.hmrc.ngrraldfrontend.repo.RaldRepo import play.twirl.api.HtmlFormat -import play.api.i18n.{I18nSupport, Messages} -import uk.gov.hmrc.govukfrontend.views.Aliases.{Fieldset, Hint, PrefixOrSuffix, Text} -import uk.gov.hmrc.govukfrontend.views.viewmodels.dateinput.{DateInput, InputItem} -import uk.gov.hmrc.govukfrontend.views.viewmodels.fieldset.{Fieldset, Legend} +import uk.gov.hmrc.govukfrontend.views.Aliases.{Hint, PrefixOrSuffix, Text} import uk.gov.hmrc.http.NotFoundException -import uk.gov.hmrc.ngrraldfrontend.views.html.InterimRentSetByTheCourtView +import uk.gov.hmrc.ngrraldfrontend.actions.{AuthRetrievals, PropertyLinkingAction} +import uk.gov.hmrc.ngrraldfrontend.config.AppConfig import uk.gov.hmrc.ngrraldfrontend.models.forms.InterimRentSetByTheCourtForm import uk.gov.hmrc.ngrraldfrontend.models.forms.InterimRentSetByTheCourtForm.form import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId - -import uk.gov.hmrc.ngrraldfrontend.views.html.components.{DateTextFields, InputText} +import uk.gov.hmrc.ngrraldfrontend.repo.RaldRepo +import uk.gov.hmrc.ngrraldfrontend.views.html.InterimRentSetByTheCourtView +import uk.gov.hmrc.ngrraldfrontend.views.html.components.InputText import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendController import javax.inject.Inject @@ -76,11 +72,24 @@ class InterimRentSetByTheCourtController @Inject()(interimRentSetByTheCourtView: (authenticate andThen hasLinkedProperties).async { implicit request => form.bindFromRequest().fold( formWithErrors => { + val correctedFormErrors = formWithErrors.errors.map { formError => + (formError.key, formError.messages) match + case (key, messages) if messages.contains("interimRentSetByTheCourt.startDate.before.1900.error") || + messages.contains("interimRentSetByTheCourt.year.required.error") => + formError.copy(key = "date.year") + case ("date.month", messages) => + formError.copy(key = "date.month") + case ("date", messages) => + formError.copy(key = "date.month") + case _ => + formError + } + val formWithCorrectedErrors = formWithErrors.copy(errors = correctedFormErrors) request.propertyLinking.map(property => Future.successful(BadRequest(interimRentSetByTheCourtView( - form = formWithErrors, + form = formWithCorrectedErrors, propertyAddress = property.addressFull, - howMuch = generateInputText(formWithErrors, "howMuch") + howMuch = generateInputText(formWithCorrectedErrors, "howMuch") )))).getOrElse(throw new NotFoundException("Couldn't find property in mongo")) }, interimRent => diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala index f19e8423..29498182 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala @@ -20,8 +20,7 @@ import play.api.data.* import play.api.data.Forms.* import play.api.data.format.Formatter import play.api.libs.json.{Json, OFormat} -import uk.gov.hmrc.ngrraldfrontend.models.forms.ProvideDetailsOfFirstSecondRentPeriodForm.isDateAfter1900 -import uk.gov.hmrc.ngrraldfrontend.models.{Month, *} +import uk.gov.hmrc.ngrraldfrontend.models.* import scala.util.Try From b02c5182025f268a6d9aec95225b88729ca9e8bc Mon Sep 17 00:00:00 2001 From: JakeReid2020 <75027964+JakeReid2020@users.noreply.github.com> Date: Wed, 17 Sep 2025 10:32:18 +0100 Subject: [PATCH 05/11] [NGR-1126] Code clean up --- app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala index c3703cc0..79f272ee 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala @@ -26,7 +26,6 @@ import java.util.Locale final case class NGRMonthYear(month: String, year: String) { def makeString: String = { - println(Console.MAGENTA_B + month.toIntOption.getOrElse(0) + Console.RESET ) val monthStr = f"${month.toIntOption.getOrElse(0)}%02d" s"$year-$monthStr" } From eee52cd922e10fe1460e55ea8b49fdfad2ba84dc Mon Sep 17 00:00:00 2001 From: JakeReid2020 <75027964+JakeReid2020@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:55:36 +0100 Subject: [PATCH 06/11] [NGR-1126] Code Clean-up --- .../InterimRentSetByTheCourtController.scala | 6 +- .../models/forms/CommonFormValidators.scala | 4 +- .../forms/InterimRentSetByTheCourtForm.scala | 41 ++++----- .../InterimRentSetByTheCourtView.scala.html | 6 +- conf/app.routes | 88 +++++++++---------- conf/messages | 6 +- ...terimRentSetByTheCourtControllerSpec.scala | 8 +- .../InterimRentSetByTheCourtFormSpec.scala | 32 +++---- 8 files changed, 93 insertions(+), 98 deletions(-) diff --git a/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala b/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala index 8a0a7097..03e60268 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtController.scala @@ -63,7 +63,7 @@ class InterimRentSetByTheCourtController @Inject()(interimRentSetByTheCourtView: Future.successful(Ok(interimRentSetByTheCourtView( form = form, propertyAddress = property.addressFull, - howMuch = generateInputText(form, "howMuch") + interimAmount = generateInputText(form, "interimAmount") )))).getOrElse(throw new NotFoundException("Couldn't find property in mongo")) } } @@ -77,8 +77,6 @@ class InterimRentSetByTheCourtController @Inject()(interimRentSetByTheCourtView: case (key, messages) if messages.contains("interimRentSetByTheCourt.startDate.before.1900.error") || messages.contains("interimRentSetByTheCourt.year.required.error") => formError.copy(key = "date.year") - case ("date.month", messages) => - formError.copy(key = "date.month") case ("date", messages) => formError.copy(key = "date.month") case _ => @@ -89,7 +87,7 @@ class InterimRentSetByTheCourtController @Inject()(interimRentSetByTheCourtView: Future.successful(BadRequest(interimRentSetByTheCourtView( form = formWithCorrectedErrors, propertyAddress = property.addressFull, - howMuch = generateInputText(formWithCorrectedErrors, "howMuch") + interimAmount = generateInputText(formWithCorrectedErrors, "interimAmount") )))).getOrElse(throw new NotFoundException("Couldn't find property in mongo")) }, interimRent => diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala index 4cbe4c12..ee6bba3b 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/CommonFormValidators.scala @@ -131,7 +131,7 @@ trait CommonFormValidators { val maybeYear = date.year.toIntOption maybeYear match { case Some(year) => - if (date.year.toInt < 1900) + if (year < 1900) Invalid (errorKey) else Valid @@ -148,7 +148,7 @@ trait CommonFormValidators { val maybeMonth = date.month.toIntOption val maybeYear = date.year.toIntOption (maybeMonth, maybeYear) match { - case (Some(month), Some(year)) if month >= 0 && month <= 12 && (month + year != 0) => + case (Some(month), Some(year)) if month > 0 && month <= 12 && (month + year != 0) => Valid case _ => Invalid(errorKey) diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala index 29498182..4eebb8ef 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala @@ -22,6 +22,7 @@ import play.api.data.format.Formatter import play.api.libs.json.{Json, OFormat} import uk.gov.hmrc.ngrraldfrontend.models.* +import scala.math.BigDecimal.RoundingMode import scala.util.Try @@ -30,11 +31,9 @@ final case class InterimRentSetByTheCourtForm(amount: BigDecimal, date: NGRMonth object InterimRentSetByTheCourtForm extends CommonFormValidators with MonthYearMappings { implicit val format: OFormat[InterimRentSetByTheCourtForm] = Json.format[InterimRentSetByTheCourtForm] - private lazy val howMuch = "howMuch" - private lazy val howMuchEmptyError = "interimRentSetByTheCourt.howMany.required.error" - private lazy val howMuchMaxError = "interimRentSetByTheCourt.howMany.tooLarge.error" - private lazy val howMuchFormatError = "interimRentSetByTheCourt.howMany.format.error" - private val dateInput = "date" + private lazy val howMuchEmptyError = "interimRentSetByTheCourt.interimAmount.required.error" + private lazy val howMuchMaxError = "interimRentSetByTheCourt.interimAmount.tooLarge.error" + private lazy val howMuchFormatError = "interimRentSetByTheCourt.interimAmount.format.error" def unapply(interimRentSetByTheCourtForm: InterimRentSetByTheCourtForm): Option[(BigDecimal, NGRMonthYear)] = Some(interimRentSetByTheCourtForm.amount, interimRentSetByTheCourtForm.date) @@ -44,28 +43,20 @@ object InterimRentSetByTheCourtForm extends CommonFormValidators with MonthYearM Year -> s"$whichDate.year.required.error" ) - def bigDecimalWithFormatError: Formatter[BigDecimal] = new Formatter[BigDecimal] { - override def bind(key: String, data: Map[String, String]): Either[Seq[FormError], BigDecimal] = { - data.get(key).filter(_.nonEmpty) match { - case Some(value) => - Try(BigDecimal(value)).toEither.left.map(_ => - Seq(FormError(key, howMuchFormatError)) - ) - case None => - Left(Seq(FormError(key, howMuchEmptyError))) - } - } - override def unbind(key: String, value: BigDecimal): Map[String, String] = - Map(key -> value.toString()) - } - - val annualRentFormMapping: (String, Mapping[BigDecimal]) = - howMuch -> of(bigDecimalWithFormatError) - .verifying(howMuchMaxError, _ <= BigDecimal("9999999.99")) - val form: Form[InterimRentSetByTheCourtForm] = Form( mapping( - annualRentFormMapping, + "interimAmount" -> text() + .transform[String](_.strip(), identity) + .verifying( + firstError( + isNotEmpty("interimAmount", howMuchEmptyError), + regexp(amountRegex.pattern(), howMuchFormatError) + ) + ) + .transform[BigDecimal](BigDecimal(_).setScale(2, RoundingMode.UP), _.toString) + .verifying( + maximumValue[BigDecimal](BigDecimal("9999999.99"), howMuchMaxError) + ), "date" -> monthYearMapping .verifying( firstError( diff --git a/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html b/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html index 6ee888c4..3dbd14fd 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html +++ b/app/uk/gov/hmrc/ngrraldfrontend/views/InterimRentSetByTheCourtView.scala.html @@ -24,14 +24,12 @@ @this( layout: Layout, formHelper: FormWithCSRF, - dateInputField: DateTextFields, inputDateForMonthYear: components.InputDateForMonthYear, - govukDateInput: GovukDateInput, govukErrorSummary: GovukErrorSummary, saveAndContinueButton: saveAndContinueButton ) -@(form:Form[InterimRentSetByTheCourtForm], propertyAddress: String, howMuch: Html)(implicit request: RequestHeader, messages: Messages, appConfig: AppConfig) +@(form:Form[InterimRentSetByTheCourtForm], propertyAddress: String, interimAmount: Html)(implicit request: RequestHeader, messages: Messages, appConfig: AppConfig) @layout(pageTitle = Some(messages("interimRentSetByTheCourt.title")), showBackLink = true, fullWidth = false) { @formHelper(action = uk.gov.hmrc.ngrraldfrontend.controllers.routes.InterimRentSetByTheCourtController.submit, Symbol("autoComplete") -> "off") { @@ -40,7 +38,7 @@ } @propertyAddress

@messages("interimRentSetByTheCourt.title")

- @howMuch + @interimAmount @inputDateForMonthYear( form, legendContent = messages("interimRentSetByTheCourt.label.2"), diff --git a/conf/app.routes b/conf/app.routes index cd354afe..273b4444 100644 --- a/conf/app.routes +++ b/conf/app.routes @@ -1,48 +1,48 @@ # microservice specific routes --> /hmrc-frontend hmrcfrontend.Routes -GET /assets/*file controllers.Assets.versioned(path = "/public", file: Asset) -GET /tell-us-about-your-new-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourNewAgreementController.show -POST /tell-us-about-your-new-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourNewAgreementController.submit -GET /tell-us-about-your-renewed-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourRenewedAgreementController.show -POST /tell-us-about-your-renewed-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourRenewedAgreementController.submit -GET /tell-us-about-rent-review uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutRentController.show -POST /tell-us-about-rent-review uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutRentController.submit -GET /what-type-of-lease-renewal-is-it uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfLeaseRenewalController.show -POST /what-type-of-lease-renewal-is-it uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfLeaseRenewalController.submit -GET /what-type-of-agreement-do-you-have uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfAgreementController.show -POST /what-type-of-agreement-do-you-have uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfAgreementController.submit -GET /landlord uk.gov.hmrc.ngrraldfrontend.controllers.LandlordController.show -POST /landlord uk.gov.hmrc.ngrraldfrontend.controllers.LandlordController.submit -GET /what-is-your-rent-based-on uk.gov.hmrc.ngrraldfrontend.controllers.WhatIsYourRentBasedOnController.show -POST /what-is-your-rent-based-on uk.gov.hmrc.ngrraldfrontend.controllers.WhatIsYourRentBasedOnController.submit -GET /how-much-is-total-annual-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowMuchIsTotalAnnualRentController.show -POST /how-much-is-total-annual-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowMuchIsTotalAnnualRentController.submit -GET /have-you-agreed-rent-changes-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.AgreedRentChangeController.show -POST /have-you-agreed-rent-changes-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.AgreedRentChangeController.submit -GET /agreement-verbal uk.gov.hmrc.ngrraldfrontend.controllers.AgreementVerbalController.show -POST /agreement-verbal uk.gov.hmrc.ngrraldfrontend.controllers.AgreementVerbalController.submit -GET /do-you-have-a-rent-free-period uk.gov.hmrc.ngrraldfrontend.controllers.CheckRentFreePeriodController.show -POST /do-you-have-a-rent-free-period uk.gov.hmrc.ngrraldfrontend.controllers.CheckRentFreePeriodController.submit -GET /agreement uk.gov.hmrc.ngrraldfrontend.controllers.AgreementController.show -POST /agreement uk.gov.hmrc.ngrraldfrontend.controllers.AgreementController.submit -GET /did-you-agree-rent-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.DidYouAgreeRentWithLandlordController.show -POST /did-you-agree-rent-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.DidYouAgreeRentWithLandlordController.submit -GET /provide-details-of-first-second-rent-period uk.gov.hmrc.ngrraldfrontend.controllers.ProvideDetailsOfFirstSecondRentPeriodController.show -POST /provide-details-of-first-second-rent-period uk.gov.hmrc.ngrraldfrontend.controllers.ProvideDetailsOfFirstSecondRentPeriodController.submit -GET /rent-periods uk.gov.hmrc.ngrraldfrontend.controllers.RentPeriodsController.show -POST /rent-periods uk.gov.hmrc.ngrraldfrontend.controllers.RentPeriodsController.submit -GET /did-the-court-set-an-interim-rent uk.gov.hmrc.ngrraldfrontend.controllers.RentInterimController.show -POST /did-the-court-set-an-interim-rent uk.gov.hmrc.ngrraldfrontend.controllers.RentInterimController.submit -GET /rent-dates-agree uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeController.show -POST /rent-dates-agree uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeController.submit -GET /rent-dates-agree-start uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeStartController.show -POST /rent-dates-agree-start uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeStartController.submit -GET /what-rent-includes uk.gov.hmrc.ngrraldfrontend.controllers.WhatYourRentIncludesController.show -POST /what-rent-includes uk.gov.hmrc.ngrraldfrontend.controllers.WhatYourRentIncludesController.submit -GET /does-rent-include-parking-spaces-or-garages uk.gov.hmrc.ngrraldfrontend.controllers.DoesYourRentIncludeParkingController.show -POST /does-rent-include-parking-spaces-or-garages uk.gov.hmrc.ngrraldfrontend.controllers.DoesYourRentIncludeParkingController.submit +-> /hmrc-frontend hmrcfrontend.Routes +GET /assets/*file controllers.Assets.versioned(path = "/public", file: Asset) +GET /tell-us-about-your-new-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourNewAgreementController.show +POST /tell-us-about-your-new-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourNewAgreementController.submit +GET /tell-us-about-your-renewed-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourRenewedAgreementController.show +POST /tell-us-about-your-renewed-agreement uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutYourRenewedAgreementController.submit +GET /tell-us-about-rent-review uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutRentController.show +POST /tell-us-about-rent-review uk.gov.hmrc.ngrraldfrontend.controllers.TellUsAboutRentController.submit +GET /what-type-of-lease-renewal-is-it uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfLeaseRenewalController.show +POST /what-type-of-lease-renewal-is-it uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfLeaseRenewalController.submit +GET /what-type-of-agreement-do-you-have uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfAgreementController.show +POST /what-type-of-agreement-do-you-have uk.gov.hmrc.ngrraldfrontend.controllers.WhatTypeOfAgreementController.submit +GET /landlord uk.gov.hmrc.ngrraldfrontend.controllers.LandlordController.show +POST /landlord uk.gov.hmrc.ngrraldfrontend.controllers.LandlordController.submit +GET /what-is-your-rent-based-on uk.gov.hmrc.ngrraldfrontend.controllers.WhatIsYourRentBasedOnController.show +POST /what-is-your-rent-based-on uk.gov.hmrc.ngrraldfrontend.controllers.WhatIsYourRentBasedOnController.submit +GET /how-much-is-total-annual-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowMuchIsTotalAnnualRentController.show +POST /how-much-is-total-annual-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowMuchIsTotalAnnualRentController.submit +GET /have-you-agreed-rent-changes-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.AgreedRentChangeController.show +POST /have-you-agreed-rent-changes-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.AgreedRentChangeController.submit +GET /agreement-verbal uk.gov.hmrc.ngrraldfrontend.controllers.AgreementVerbalController.show +POST /agreement-verbal uk.gov.hmrc.ngrraldfrontend.controllers.AgreementVerbalController.submit +GET /do-you-have-a-rent-free-period uk.gov.hmrc.ngrraldfrontend.controllers.CheckRentFreePeriodController.show +POST /do-you-have-a-rent-free-period uk.gov.hmrc.ngrraldfrontend.controllers.CheckRentFreePeriodController.submit +GET /agreement uk.gov.hmrc.ngrraldfrontend.controllers.AgreementController.show +POST /agreement uk.gov.hmrc.ngrraldfrontend.controllers.AgreementController.submit +GET /did-you-agree-rent-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.DidYouAgreeRentWithLandlordController.show +POST /did-you-agree-rent-with-landlord uk.gov.hmrc.ngrraldfrontend.controllers.DidYouAgreeRentWithLandlordController.submit +GET /provide-details-of-first-second-rent-period uk.gov.hmrc.ngrraldfrontend.controllers.ProvideDetailsOfFirstSecondRentPeriodController.show +POST /provide-details-of-first-second-rent-period uk.gov.hmrc.ngrraldfrontend.controllers.ProvideDetailsOfFirstSecondRentPeriodController.submit +GET /rent-periods uk.gov.hmrc.ngrraldfrontend.controllers.RentPeriodsController.show +POST /rent-periods uk.gov.hmrc.ngrraldfrontend.controllers.RentPeriodsController.submit +GET /did-the-court-set-an-interim-rent uk.gov.hmrc.ngrraldfrontend.controllers.RentInterimController.show +POST /did-the-court-set-an-interim-rent uk.gov.hmrc.ngrraldfrontend.controllers.RentInterimController.submit +GET /rent-dates-agree uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeController.show +POST /rent-dates-agree uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeController.submit +GET /rent-dates-agree-start uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeStartController.show +POST /rent-dates-agree-start uk.gov.hmrc.ngrraldfrontend.controllers.RentDatesAgreeStartController.submit +GET /what-rent-includes uk.gov.hmrc.ngrraldfrontend.controllers.WhatYourRentIncludesController.show +POST /what-rent-includes uk.gov.hmrc.ngrraldfrontend.controllers.WhatYourRentIncludesController.submit +GET /does-rent-include-parking-spaces-or-garages uk.gov.hmrc.ngrraldfrontend.controllers.DoesYourRentIncludeParkingController.show +POST /does-rent-include-parking-spaces-or-garages uk.gov.hmrc.ngrraldfrontend.controllers.DoesYourRentIncludeParkingController.submit GET /how-many-parking-spaces-or-garages-included-in-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowManyParkingSpacesOrGaragesIncludedInRentController.show POST /how-many-parking-spaces-or-garages-included-in-rent uk.gov.hmrc.ngrraldfrontend.controllers.HowManyParkingSpacesOrGaragesIncludedInRentController.submit -GET /interim-rent-set-by-court uk.gov.hmrc.ngrraldfrontend.controllers.InterimRentSetByTheCourtController.show -POST /interim-rent-set-by-court uk.gov.hmrc.ngrraldfrontend.controllers.InterimRentSetByTheCourtController.submit \ No newline at end of file +GET /interim-rent-set-by-court uk.gov.hmrc.ngrraldfrontend.controllers.InterimRentSetByTheCourtController.show +POST /interim-rent-set-by-court uk.gov.hmrc.ngrraldfrontend.controllers.InterimRentSetByTheCourtController.submit \ No newline at end of file diff --git a/conf/messages b/conf/messages index 73707a72..bdc13cf4 100644 --- a/conf/messages +++ b/conf/messages @@ -360,9 +360,9 @@ interimRentSetByTheCourt.hint.2 = For example, 6 2026 date.month = Month date.year = Year -interimRentSetByTheCourt.howMany.required.error = Enter how much the interim rent was, in pounds -interimRentSetByTheCourt.howMany.tooLarge.error = Interim rent must be £9,999,999.99 or less -interimRentSetByTheCourt.howMany.format.error = Interim rent must be a number, like 50,000 +interimRentSetByTheCourt.interimAmount.required.error = Enter how much the interim rent was, in pounds +interimRentSetByTheCourt.interimAmount.tooLarge.error = Interim rent must be £9,999,999.99 or less +interimRentSetByTheCourt.interimAmount.format.error = Interim rent must be a number, like 50,000 interimRentSetByTheCourt.monthYear.format.error = Date your interim rent started must be a real date interimRentSetByTheCourt.required.error = Enter the date you started paying interim rent interimRentSetByTheCourt.month.required.error = Date you started paying the interim rent must include a month diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala index c1ed8b98..1d42c231 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala @@ -76,7 +76,7 @@ class InterimRentSetByTheCourtControllerSpec extends ControllerSpecSupport { "Return OK and the correct view" in { val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit) .withFormUrlEncodedBody( - "howMuch" -> "10000", + "interimAmount" -> "10000", "date.month" -> "1", "date.year" -> "1990" ) @@ -98,6 +98,8 @@ class InterimRentSetByTheCourtControllerSpec extends ControllerSpecSupport { val result = controller.submit()(authenticatedFakeRequest(fakePostRequest)) status(result) mustBe BAD_REQUEST + val content = contentAsString(result) + content must include("Enter how much the interim rent was, in pounds") } "Return BAD_REQUEST for missing month input and the correct view" in { mockRequest() @@ -111,6 +113,8 @@ class InterimRentSetByTheCourtControllerSpec extends ControllerSpecSupport { val result = controller.submit()(authenticatedFakeRequest(fakePostRequest)) status(result) mustBe BAD_REQUEST + val content = contentAsString(result) + content must include("Date you started paying the interim rent must include a month") } "Return BAD_REQUEST for missing year input and the correct view" in { mockRequest() @@ -124,6 +128,8 @@ class InterimRentSetByTheCourtControllerSpec extends ControllerSpecSupport { val result = controller.submit()(authenticatedFakeRequest(fakePostRequest)) status(result) mustBe BAD_REQUEST + val content = contentAsString(result) + content must include("Date you started paying the interim rent must include a year") } "Return Exception if no address is in the mongo" in { mockRequestWithoutProperty() diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala index 8087421a..ac3037ce 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala @@ -23,13 +23,15 @@ import play.api.data.FormError import play.api.libs.json.Json import uk.gov.hmrc.ngrraldfrontend.models.NGRMonthYear +import scala.collection.immutable.ArraySeq + class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers { "InterimRentSetByTheCourtForm" should { "bind valid input" in { val data = Map( - "howMuch" -> "123456.78", + "interimAmount" -> "123456.78", "date.month" -> "1", "date.year" -> "1990" ) @@ -37,7 +39,7 @@ class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers { boundForm.hasErrors shouldBe false boundForm.value shouldBe Some(InterimRentSetByTheCourtForm( - amount = BigDecimal("123456.78"), + amount = BigDecimal(123456.78), date = NGRMonthYear(month = "1", year = "1990") )) } @@ -47,34 +49,34 @@ class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers { val boundForm = InterimRentSetByTheCourtForm.form.bind(data) boundForm.hasErrors shouldBe true - boundForm.errors should contain(FormError("howMuch", "interimRentSetByTheCourt.howMany.required.error")) + boundForm.errors should contain(FormError("interimAmount", "error.required")) } "fail to bind non-numeric input for how much input field" in { val data = Map( - "howMuch" -> "hello", + "interimAmount" -> "hello", "date.month" -> "1", "date.year" -> "1990" ) val boundForm = InterimRentSetByTheCourtForm.form.bind(data) - - boundForm.errors should contain(FormError("howMuch", "interimRentSetByTheCourt.howMany.format.error")) + boundForm.hasErrors shouldBe true + boundForm.errors shouldBe List(FormError("interimAmount", List("interimRentSetByTheCourt.interimAmount.format.error"), ArraySeq("""([0-9]+\.[0-9]+|[0-9]+)"""))) } "fail to bind input greater than 9999999.99 for how much input field" in { val data = Map( - "howMuch" -> "123456789.78", + "interimAmount" -> "123456789.78", "date.month" -> "1", "date.year" -> "1990" ) val boundForm = InterimRentSetByTheCourtForm.form.bind(data) - boundForm.errors should contain(FormError("howMuch", "interimRentSetByTheCourt.howMany.tooLarge.error")) + boundForm.errors shouldBe List(FormError("interimAmount", List("interimRentSetByTheCourt.interimAmount.tooLarge.error"), ArraySeq(9999999.99))) } "bind edge case of exactly 9999999.99" in { val data = Map( - "howMuch" -> "9999999.99", + "interimAmount" -> "9999999.99", "date.month" -> "1", "date.year" -> "1990" ) @@ -89,7 +91,7 @@ class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers { "fail to bind incorrect month for month input field" in { val data = Map( - "howMuch" -> "123456.78", + "interimAmount" -> "123456.78", "date.month" -> "13", "date.year" -> "1990" ) @@ -99,7 +101,7 @@ class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers { } "fail to bind year before 1900 for year input field" in { val data = Map( - "howMuch" -> "123456.78", + "interimAmount" -> "123456.78", "date.month" -> "10", "date.year" -> "1899" ) @@ -110,7 +112,7 @@ class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers { "fail to bind missing month input" in { val data = Map( - "howMuch" -> "123456.78", + "interimAmount" -> "123456.78", "date.month" -> "", "date.year" -> "1899" ) @@ -121,7 +123,7 @@ class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers { "fail to bind missing year input" in { val data = Map( - "howMuch" -> "123456.78", + "interimAmount" -> "123456.78", "date.month" -> "1", "date.year" -> "" ) @@ -132,7 +134,7 @@ class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers { "fail to bind non numeric format for month input" in { val data = Map( - "howMuch" -> "123456.78", + "interimAmount" -> "123456.78", "date.month" -> "hello", "date.year" -> "1999" ) @@ -143,7 +145,7 @@ class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers { "fail to bind non numeric format for year input" in { val data = Map( - "howMuch" -> "123456.78", + "interimAmount" -> "123456.78", "date.month" -> "1", "date.year" -> "hello" ) From d5f9a9ff6d9fa1a40f8f4ada1c843f6a7ebfc444 Mon Sep 17 00:00:00 2001 From: JakeReid2020 <75027964+JakeReid2020@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:06:42 +0100 Subject: [PATCH 07/11] [NGR-1126] Allowing commas to be added --- .../forms/HowMuchIsTotalAnnualRentForm.scala | 2 +- .../forms/InterimRentSetByTheCourtForm.scala | 2 +- ...rovideDetailsOfFirstSecondRentPeriodForm.scala | 2 +- .../forms/HowMuchIsTotalAnnualRentFormSpec.scala | 10 ++++++++++ .../forms/InterimRentSetByTheCourtFormSpec.scala | 15 +++++++++++++++ 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentForm.scala index 1d946975..592bf17e 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentForm.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentForm.scala @@ -41,7 +41,7 @@ object HowMuchIsTotalAnnualRentForm extends CommonFormValidators { val form: Form[HowMuchIsTotalAnnualRentForm] = Form( mapping( annualRent -> text() - .transform[String](_.strip(), identity) + .transform[String](_.strip().replaceAll("[£|,|\\s]", ""), identity) .verifying( firstError( isNotEmpty(annualRent, annualRentEmptyError), diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala index 4eebb8ef..c5314370 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala @@ -46,7 +46,7 @@ object InterimRentSetByTheCourtForm extends CommonFormValidators with MonthYearM val form: Form[InterimRentSetByTheCourtForm] = Form( mapping( "interimAmount" -> text() - .transform[String](_.strip(), identity) + .transform[String](_.strip().replaceAll("[£|,|\\s]", ""), identity) .verifying( firstError( isNotEmpty("interimAmount", howMuchEmptyError), diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/ProvideDetailsOfFirstSecondRentPeriodForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/ProvideDetailsOfFirstSecondRentPeriodForm.scala index 68823ba3..7b579539 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/ProvideDetailsOfFirstSecondRentPeriodForm.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/ProvideDetailsOfFirstSecondRentPeriodForm.scala @@ -129,7 +129,7 @@ object ProvideDetailsOfFirstSecondRentPeriodForm extends CommonFormValidators wi ) ), SecondRentPeriodAmount -> text() - .transform[String](_.strip(), identity) + .transform[String](_.strip().replaceAll("[£|,|\\s]", ""), identity) .verifying( firstError( isNotEmpty(SecondRentPeriodAmount, annualRentEmptyError), diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentFormSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentFormSpec.scala index 77e5b970..bfd96dda 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentFormSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/HowMuchIsTotalAnnualRentFormSpec.scala @@ -37,6 +37,16 @@ class HowMuchIsTotalAnnualRentFormSpec extends AnyWordSpec with Matchers { boundForm.value shouldBe Some(HowMuchIsTotalAnnualRentForm(BigDecimal("123456.78"))) } + "bind amount with commas" in { + val data = Map( + "how–much–is–total–annual–rent-value" -> "9,999,999.99", + ) + val boundForm = HowMuchIsTotalAnnualRentForm.form.bind(data) + + boundForm.hasErrors shouldBe false + boundForm.value shouldBe Some(HowMuchIsTotalAnnualRentForm(BigDecimal("9999999.99"))) + } + "fail to bind empty input" in { val data = Map("how–much–is–total–annual–rent-value" -> "") val boundForm = HowMuchIsTotalAnnualRentForm.form.bind(data) diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala index ac3037ce..1013d551 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala @@ -89,6 +89,21 @@ class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers { )) } + "bind amount with commas" in { + val data = Map( + "interimAmount" -> "9,999,999.99", + "date.month" -> "1", + "date.year" -> "1990" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.hasErrors shouldBe false + boundForm.value shouldBe Some(InterimRentSetByTheCourtForm( + amount = BigDecimal("9999999.99"), + date = NGRMonthYear(month = "1", year = "1990") + )) + } + "fail to bind incorrect month for month input field" in { val data = Map( "interimAmount" -> "123456.78", From df4ce5cb50556d9810e234b1b6de1ec867690e6d Mon Sep 17 00:00:00 2001 From: JakeReid2020 <75027964+JakeReid2020@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:16:45 +0100 Subject: [PATCH 08/11] [NGR-1126] Fixing test --- .../InterimRentSetByTheCourtControllerSpec.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala index 1d42c231..f8b0f019 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala @@ -90,7 +90,7 @@ class InterimRentSetByTheCourtControllerSpec extends ControllerSpecSupport { mockRequest() val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit) .withFormUrlEncodedBody( - "howMuch" -> "", + "interimAmount" -> "", "date.month" -> "1", "date.year" -> "1990" ) @@ -105,7 +105,7 @@ class InterimRentSetByTheCourtControllerSpec extends ControllerSpecSupport { mockRequest() val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit) .withFormUrlEncodedBody( - "howMuch" -> "1000", + "interimAmount" -> "1000", "date.month" -> "", "date.year" -> "1990" ) @@ -120,7 +120,7 @@ class InterimRentSetByTheCourtControllerSpec extends ControllerSpecSupport { mockRequest() val fakePostRequest = FakeRequest(routes.InterimRentSetByTheCourtController.submit) .withFormUrlEncodedBody( - "howMuch" -> "1000", + "interimAmount" -> "1000", "date.month" -> "1", "date.year" -> "" ) From 9b78f1630247e315b4090d153b16ad1b0b3f986f Mon Sep 17 00:00:00 2001 From: JakeReid2020 <75027964+JakeReid2020@users.noreply.github.com> Date: Wed, 17 Sep 2025 15:52:52 +0100 Subject: [PATCH 09/11] [NGR-1126] Adding Repo test --- .../models/InterimRentSetByTheCourt.scala | 11 +++++++++++ .../hmrc/ngrraldfrontend/models/NGRMonthYear.scala | 6 +----- .../hmrc/ngrraldfrontend/models/RaldUserAnswers.scala | 3 ++- .../ProvideDetailsOfFirstSecondRentPeriodForm.scala | 2 +- .../gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala | 6 ++++++ 5 files changed, 21 insertions(+), 7 deletions(-) create mode 100644 app/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourt.scala diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourt.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourt.scala new file mode 100644 index 00000000..454c1978 --- /dev/null +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourt.scala @@ -0,0 +1,11 @@ +package uk.gov.hmrc.ngrraldfrontend.models + +import play.api.libs.json.{Json, OFormat} + +case class InterimRentSetByTheCourt(amount: String, + date: String + ) + +object InterimRentSetByTheCourt { + implicit val format: OFormat[InterimRentSetByTheCourt] = Json.format[InterimRentSetByTheCourt] +} \ No newline at end of file diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala index 79f272ee..4cae8fd2 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/NGRMonthYear.scala @@ -52,8 +52,4 @@ trait MonthYearMappings { "year" -> text().transform(_.strip(), identity), )(NGRMonthYear.apply)(NGRMonthYear.unapply) } -} - -def monthYearErrorKeys(pageName: String, whichDate: String): Map[DateErrorKeys, String] = Map( - Required -> s"$pageName.$whichDate.required.error" -) \ No newline at end of file +} \ No newline at end of file diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswers.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswers.scala index f8887264..8d39f6fe 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswers.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswers.scala @@ -40,7 +40,8 @@ final case class RaldUserAnswers( hasAnotherRentPeriod: Option[Boolean] = None, whatYourRentIncludes: Option[WhatYourRentIncludes] = None, doesYourRentIncludeParking: Option[Boolean] = None, - howManyParkingSpacesOrGaragesIncludedInRent: Option[HowManyParkingSpacesOrGarages] = None + howManyParkingSpacesOrGaragesIncludedInRent: Option[HowManyParkingSpacesOrGarages] = None , + interimRentSetByTheCourt: Option[InterimRentSetByTheCourt] = None ) diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/ProvideDetailsOfFirstSecondRentPeriodForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/ProvideDetailsOfFirstSecondRentPeriodForm.scala index 7b579539..94cfb082 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/ProvideDetailsOfFirstSecondRentPeriodForm.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/ProvideDetailsOfFirstSecondRentPeriodForm.scala @@ -110,7 +110,7 @@ object ProvideDetailsOfFirstSecondRentPeriodForm extends CommonFormValidators wi firstRentPeriodRadio -> radioText(radioFirstPeriodRequiredError), RentPeriodAmount -> optional( text() - .transform[String](_.strip(), identity) + .transform[String](_.strip().replaceAll("[£|,|\\s]", ""), identity) ), secondDateStartInput -> dateMapping .verifying( diff --git a/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala index df05ff85..3be542f1 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala @@ -505,6 +505,12 @@ class RaldRepoSpec extends TestSupport with TestData actual shouldBe Some(RaldUserAnswers(credId, NewAgreement, property, doesYourRentIncludeParking = Some(true))) } + "insert interim rent amount and start date" in { + await(repository.insertInterimRentSetByTheCourt(credId, 10000.00, "2020-1")) + val actual = await(repository.findByCredId(credId)) + actual shouldBe Some(RaldUserAnswers(credId, NewAgreement, property, interimRentSetByTheCourt = Some(InterimRentSetByTheCourt(amount = "10000.0", date = "2020-1")))) + } + "insert has parking included in rent successfully with no" in { await(repository.insertDoesYourRentIncludeParking(credId, "No")) val actual = await(repository.findByCredId(credId)) From 46aa7c167208edd3b0f3f92b869364bb8de26e21 Mon Sep 17 00:00:00 2001 From: JakeReid2020 <75027964+JakeReid2020@users.noreply.github.com> Date: Thu, 18 Sep 2025 08:55:39 +0100 Subject: [PATCH 10/11] [NGR-1126] Changing rounding and adding to the RaldUserAnswers --- .../models/InterimRentSetByTheCourt.scala | 16 +++++++ .../forms/InterimRentSetByTheCourtForm.scala | 4 +- .../models/InterimRentSetByTheCourtSpec.scala | 44 ++++++++++++++++++ .../InterimRentSetByTheCourtFormSpec.scala | 45 +++++++++++++++++++ .../ngrraldfrontend/repo/RaldRepoSpec.scala | 8 +++- 5 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 test/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourtSpec.scala diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourt.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourt.scala index 454c1978..6f0950f3 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourt.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourt.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2025 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package uk.gov.hmrc.ngrraldfrontend.models import play.api.libs.json.{Json, OFormat} diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala index c5314370..5daa5d7e 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtForm.scala @@ -42,7 +42,7 @@ object InterimRentSetByTheCourtForm extends CommonFormValidators with MonthYearM Month -> s"$whichDate.month.required.error", Year -> s"$whichDate.year.required.error" ) - + val form: Form[InterimRentSetByTheCourtForm] = Form( mapping( "interimAmount" -> text() @@ -53,7 +53,7 @@ object InterimRentSetByTheCourtForm extends CommonFormValidators with MonthYearM regexp(amountRegex.pattern(), howMuchFormatError) ) ) - .transform[BigDecimal](BigDecimal(_).setScale(2, RoundingMode.UP), _.toString) + .transform[BigDecimal](BigDecimal(_).setScale(2, RoundingMode.HALF_UP), _.toString) .verifying( maximumValue[BigDecimal](BigDecimal("9999999.99"), howMuchMaxError) ), diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourtSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourtSpec.scala new file mode 100644 index 00000000..b9e92844 --- /dev/null +++ b/test/uk/gov/hmrc/ngrraldfrontend/models/InterimRentSetByTheCourtSpec.scala @@ -0,0 +1,44 @@ +/* + * Copyright 2025 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.gov.hmrc.ngrraldfrontend.models + +import play.api.libs.json.{JsValue, Json} +import uk.gov.hmrc.ngrraldfrontend.helpers.TestSupport + +class InterimRentSetByTheCourtSpec extends TestSupport { + + val interimRentSetByTheCourt: InterimRentSetByTheCourt = InterimRentSetByTheCourt(amount = "1000.00", date = "2020-1") + + val interimRentSetByTheCourtJson: JsValue = Json.parse( + """ + |{ + |"amount": "1000.00", + |"date":"2020-1" + |} + |""".stripMargin + ) + + "RentBasedOn" should { + "deserialize to json" in { + Json.toJson(interimRentSetByTheCourt) mustBe interimRentSetByTheCourtJson + } + "serialize to json" in { + interimRentSetByTheCourtJson.as[InterimRentSetByTheCourt] mustBe interimRentSetByTheCourt + } + } +} + diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala index 1013d551..b499801b 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/InterimRentSetByTheCourtFormSpec.scala @@ -89,6 +89,51 @@ class InterimRentSetByTheCourtFormSpec extends AnyWordSpec with Matchers { )) } + "bind and drop decimal places to make 2" in { + val data = Map( + "interimAmount" -> "11.123", + "date.month" -> "1", + "date.year" -> "1990" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.hasErrors shouldBe false + boundForm.value shouldBe Some(InterimRentSetByTheCourtForm( + amount = BigDecimal("11.12"), + date = NGRMonthYear(month = "1", year = "1990") + )) + } + + "bind and round the decimal places up" in { + val data = Map( + "interimAmount" -> "11.125", + "date.month" -> "1", + "date.year" -> "1990" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.hasErrors shouldBe false + boundForm.value shouldBe Some(InterimRentSetByTheCourtForm( + amount = BigDecimal("11.13"), + date = NGRMonthYear(month = "1", year = "1990") + )) + } + + "bind decimal with two .00" in { + val data = Map( + "interimAmount" -> "11.00", + "date.month" -> "1", + "date.year" -> "1990" + ) + val boundForm = InterimRentSetByTheCourtForm.form.bind(data) + + boundForm.hasErrors shouldBe false + boundForm.value shouldBe Some(InterimRentSetByTheCourtForm( + amount = BigDecimal("11.00"), + date = NGRMonthYear(month = "1", year = "1990") + )) + } + "bind amount with commas" in { val data = Map( "interimAmount" -> "9,999,999.99", diff --git a/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala index 3be542f1..cf2974a4 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala @@ -506,9 +506,15 @@ class RaldRepoSpec extends TestSupport with TestData } "insert interim rent amount and start date" in { + await(repository.insertInterimRentSetByTheCourt(credId, 10000.12, "2020-1")) + val actual = await(repository.findByCredId(credId)) + actual shouldBe Some(RaldUserAnswers(credId, NewAgreement, property, interimRentSetByTheCourt = Some(InterimRentSetByTheCourt(amount = "10000.12", date = "2020-1")))) + } + + "insert interim rent amount With decimal of .00 and start date" in { await(repository.insertInterimRentSetByTheCourt(credId, 10000.00, "2020-1")) val actual = await(repository.findByCredId(credId)) - actual shouldBe Some(RaldUserAnswers(credId, NewAgreement, property, interimRentSetByTheCourt = Some(InterimRentSetByTheCourt(amount = "10000.0", date = "2020-1")))) + actual shouldBe Some(RaldUserAnswers(credId, NewAgreement, property, interimRentSetByTheCourt = Some(InterimRentSetByTheCourt(amount = "10000.0", date = "2020-1")))) } "insert has parking included in rent successfully with no" in { From 7403545f6e49ef497fbfa78a141331e7afa9ff50 Mon Sep 17 00:00:00 2001 From: JakeReid2020 <75027964+JakeReid2020@users.noreply.github.com> Date: Thu, 18 Sep 2025 09:01:49 +0100 Subject: [PATCH 11/11] [NGR-1126] Rebase --- .../controllers/InterimRentSetByTheCourtControllerSpec.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala index f8b0f019..284a8f3c 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/InterimRentSetByTheCourtControllerSpec.scala @@ -46,7 +46,6 @@ import uk.gov.hmrc.ngrraldfrontend.views.html.components.InputText class InterimRentSetByTheCourtControllerSpec extends ControllerSpecSupport { val pageTitle = "Interim rent set by the court" val view: InterimRentSetByTheCourtView = inject[InterimRentSetByTheCourtView] - val mockInputText: InputText = inject[InputText] val controller: InterimRentSetByTheCourtController = new InterimRentSetByTheCourtController( interimRentSetByTheCourtView = view, authenticate = mockAuthJourney,