diff --git a/app/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentController.scala b/app/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentController.scala index 74b051bc..24c9921c 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentController.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentController.scala @@ -62,7 +62,11 @@ class HowManyParkingSpacesOrGaragesIncludedInRentController @Inject()(howManyPar (authenticate andThen getData).async { implicit request => val preparedForm = request.userAnswers.getOrElse(UserAnswers(request.credId)).get(HowManyParkingSpacesOrGaragesIncludedInRentPage) match { case None => form - case Some(value) => form.fill(HowManyParkingSpacesOrGaragesIncludedInRentForm(value.uncoveredSpaces.toInt, value.coveredSpaces.toInt, value.garages.toInt)) + case Some(value) => form.fill(HowManyParkingSpacesOrGaragesIncludedInRentForm( + value.uncoveredSpaces, + value.coveredSpaces, + value.garages + )) } Future.successful(Ok(howManyParkingSpacesOrGaragesIncludedInRentView( form = preparedForm, @@ -81,7 +85,6 @@ class HowManyParkingSpacesOrGaragesIncludedInRentController @Inject()(howManyPar formWithErrors => { val formWithCorrectedErrors = formWithErrors.errors.head match { case value if value.key.isEmpty && - value.messages.contains("howManyParkingSpacesOrGaragesIncludedInRent.allFields.error.required") || value.messages.contains("howManyParkingSpacesOrGaragesIncludedInRent.error.required") => val uncoveredSpaces = value.copy(key = "uncoveredSpaces") val coveredSpaces = value.copy(key = "coveredSpaces") @@ -99,7 +102,7 @@ class HowManyParkingSpacesOrGaragesIncludedInRentController @Inject()(howManyPar ))) }, parkingSpacesOrGaragesIncluded => - val answers = HowManyParkingSpacesOrGarages(parkingSpacesOrGaragesIncluded.uncoveredSpaces.toString, parkingSpacesOrGaragesIncluded.coveredSpaces.toString, parkingSpacesOrGaragesIncluded.garages.toString) + val answers = HowManyParkingSpacesOrGarages(parkingSpacesOrGaragesIncluded.uncoveredSpaces, parkingSpacesOrGaragesIncluded.coveredSpaces, parkingSpacesOrGaragesIncluded.garages) for { updatedAnswers <- Future.fromTry(request.userAnswers.getOrElse(UserAnswers(request.credId)).set(HowManyParkingSpacesOrGaragesIncludedInRentPage, answers)) _ <- sessionRepository.set(updatedAnswers) diff --git a/app/uk/gov/hmrc/ngrraldfrontend/controllers/RepairsAndInsuranceController.scala b/app/uk/gov/hmrc/ngrraldfrontend/controllers/RepairsAndInsuranceController.scala new file mode 100644 index 00000000..a46f2c84 --- /dev/null +++ b/app/uk/gov/hmrc/ngrraldfrontend/controllers/RepairsAndInsuranceController.scala @@ -0,0 +1,85 @@ +/* + * 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.i18n.I18nSupport +import play.api.mvc.{Action, AnyContent, MessagesControllerComponents} +import uk.gov.hmrc.ngrraldfrontend.actions.{AuthRetrievals, DataRetrievalAction} +import uk.gov.hmrc.ngrraldfrontend.config.AppConfig +import uk.gov.hmrc.ngrraldfrontend.models.components.* +import uk.gov.hmrc.ngrraldfrontend.models.components.NGRRadio.buildRadios +import uk.gov.hmrc.ngrraldfrontend.models.forms.RepairsAndInsuranceForm +import uk.gov.hmrc.ngrraldfrontend.models.forms.RepairsAndInsuranceForm.form +import uk.gov.hmrc.ngrraldfrontend.models.{Mode, RepairsAndInsurance, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.navigation.Navigator +import uk.gov.hmrc.ngrraldfrontend.pages.RepairsAndInsurancePage +import uk.gov.hmrc.ngrraldfrontend.repo.SessionRepository +import uk.gov.hmrc.ngrraldfrontend.views.html.RepairsAndInsuranceView +import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendController + +import javax.inject.Inject +import scala.concurrent.{ExecutionContext, Future} + +class RepairsAndInsuranceController @Inject()(repairsAndInsuranceView: RepairsAndInsuranceView, + authenticate: AuthRetrievals, + navigator: Navigator, + getData: DataRetrievalAction, + sessionRepository: SessionRepository, + mcc: MessagesControllerComponents)(implicit appConfig: AppConfig, ec: ExecutionContext) + extends FrontendController(mcc) with I18nSupport { + + def show(mode: Mode): Action[AnyContent] = { + (authenticate andThen getData).async { implicit request => + val preparedForm = request.userAnswers.getOrElse(UserAnswers(request.credId)).get(RepairsAndInsurancePage) match { + case None => form + case Some(value) => form.fill(RepairsAndInsuranceForm(value.internalRepairs, value.externalRepairs, value.buildingInsurance)) + } + Future.successful(Ok(repairsAndInsuranceView( + form = preparedForm, + internalRepairs = buildRadios(preparedForm, RepairsAndInsuranceForm.ngrRadio(preparedForm, "internalRepairs")), + externalRepairs = buildRadios(preparedForm, RepairsAndInsuranceForm.ngrRadio(preparedForm, "externalRepairs")), + buildingInsurance = buildRadios(preparedForm, RepairsAndInsuranceForm.ngrRadio(preparedForm, "buildingInsurance")), + propertyAddress = request.property.addressFull, + mode + ))) + } + } + + def submit(mode: Mode): Action[AnyContent] = + (authenticate andThen getData).async { implicit request => + form.bindFromRequest().fold( + formWithErrors => { + Future.successful(BadRequest(repairsAndInsuranceView( + form = formWithErrors, + internalRepairs = buildRadios(formWithErrors, RepairsAndInsuranceForm.ngrRadio(formWithErrors, "internalRepairs")), + externalRepairs = buildRadios(formWithErrors, RepairsAndInsuranceForm.ngrRadio(formWithErrors, "externalRepairs")), + buildingInsurance = buildRadios(formWithErrors, RepairsAndInsuranceForm.ngrRadio(formWithErrors, "buildingInsurance")), + propertyAddress = request.property.addressFull, + mode + ))) + }, + repairsAndInsurance => + val answers = RepairsAndInsurance(repairsAndInsurance.internalRepairs, repairsAndInsurance.externalRepairs, repairsAndInsurance.buildingInsurance) + for{ + updatedAnswers <- Future.fromTry(request.userAnswers.getOrElse(UserAnswers(request.credId)).set(RepairsAndInsurancePage, answers)) + _ <- sessionRepository.set(updatedAnswers) + } yield Redirect(navigator.nextPage(RepairsAndInsurancePage, mode, updatedAnswers)) + ) + } +} + + diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/HowManyParkingSpacesOrGarages.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/HowManyParkingSpacesOrGarages.scala index 23f82640..9ed2a4cc 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/HowManyParkingSpacesOrGarages.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/HowManyParkingSpacesOrGarages.scala @@ -19,9 +19,9 @@ package uk.gov.hmrc.ngrraldfrontend.models import play.api.libs.json.{Json, OFormat} case class HowManyParkingSpacesOrGarages( - uncoveredSpaces: String, - coveredSpaces: String, - garages: String, + uncoveredSpaces: Int, + coveredSpaces: Int, + garages: Int, ) object HowManyParkingSpacesOrGarages { diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswers.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswers.scala deleted file mode 100644 index c0f38c1f..00000000 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswers.scala +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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.{Format, Json} -import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId -import uk.gov.hmrc.ngrraldfrontend.models.vmvProperty.VMVProperty - -final case class RaldUserAnswers( - credId: CredId, - agreementType: AgreementType, - selectedProperty: VMVProperty, - whatTypeOfAgreement: Option[String] = None, - whatTypeOfRenewal: Option[String] = None, - landlord: Option[Landlord] = None, - rentBasedOn: Option[RentBasedOn] = None, - rentAmount:Option[String] = None, - agreedRentChange: Option[String] = None, - agreementVerbal: Option[AgreementVerbal] = None, - hasRentFreePeriod: Option[Boolean] = None, - agreement: Option[Agreement] = None, - provideDetailsOfFirstSecondRentPeriod: Option[ProvideDetailsOfFirstSecondRentPeriod] = None, - didYouAgreeRentWithLandlord: Option[Boolean] = None, - agreedRentDate: Option[String] = None, - rentDatesAgreeStart: Option[RentDatesAgreeStart] = None, - hasAnotherRentPeriod: Option[Boolean] = None, - whatYourRentIncludes: Option[WhatYourRentIncludes] = None, - doesYourRentIncludeParking: Option[Boolean] = None, - howManyParkingSpacesOrGaragesIncludedInRent: Option[HowManyParkingSpacesOrGarages] = None, - interimRentSetByTheCourt: Option[InterimRentSetByTheCourt] = None, - rentFreePeriod: Option[RentFreePeriod] = None - ) - - -object RaldUserAnswers{ - implicit val format:Format[RaldUserAnswers] = Json.format[RaldUserAnswers] -} \ No newline at end of file diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/RepairsAndInsurance.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/RepairsAndInsurance.scala new file mode 100644 index 00000000..65077f55 --- /dev/null +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/RepairsAndInsurance.scala @@ -0,0 +1,29 @@ +/* + * 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} + +case class RepairsAndInsurance( + internalRepairs: String, + externalRepairs: String, + buildingInsurance: String + ) + +object RepairsAndInsurance { + implicit val format: OFormat[RepairsAndInsurance] = Json.format[RepairsAndInsurance] +} \ No newline at end of file diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/components/NGRRadio.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/components/NGRRadio.scala index 52fc372f..07941cc3 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/components/NGRRadio.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/components/NGRRadio.scala @@ -81,6 +81,16 @@ case object rentIncWaterChargesNo extends WhatYourRentIncludesRadio case object rentIncServiceYes extends WhatYourRentIncludesRadio case object rentIncServiceNo extends WhatYourRentIncludesRadio +sealed trait RepairsAndInsurance extends RadioEntry +case object InternalRepairsYou extends RepairsAndInsurance +case object InternalRepairsLandlord extends RepairsAndInsurance +case object InternalRepairsYouAndLandlord extends RepairsAndInsurance +case object ExternalRepairsYou extends RepairsAndInsurance +case object ExternalRepairsLandlord extends RepairsAndInsurance +case object ExternalRepairsYouAndLandlord extends RepairsAndInsurance +case object BuildingInsuranceYou extends RepairsAndInsurance +case object BuildingInsuranceLandlord extends RepairsAndInsurance +case object LandlordYouAndLandlord extends RepairsAndInsurance case class NGRRadioName(key: String) diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/HowManyParkingSpacesOrGaragesIncludedInRentForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/HowManyParkingSpacesOrGaragesIncludedInRentForm.scala index c9517c0c..dd1d8dab 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/HowManyParkingSpacesOrGaragesIncludedInRentForm.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/HowManyParkingSpacesOrGaragesIncludedInRentForm.scala @@ -55,8 +55,7 @@ object HowManyParkingSpacesOrGaragesIncludedInRentForm extends CommonFormValidat Constraint((input: A) => { val formData = input.asInstanceOf[HowManyParkingSpacesOrGaragesIncludedInRentForm] (formData.uncoveredSpaces, formData.coveredSpaces, formData.garages) match { - case (-1,-1,-1) => Invalid(allFieldsRequiredError) - case (0, 0, 0) => Invalid(fieldRequired) + case (uncoveredSpaces, coveredSpaces, garages) if uncoveredSpaces + coveredSpaces + garages <= 0 => Invalid(fieldRequired) case (_,_,_)=> Valid } }) @@ -73,7 +72,7 @@ object HowManyParkingSpacesOrGaragesIncludedInRentForm extends CommonFormValidat isLargerThanInt(maxValue, uncoveredSpacesTooHighError) ) ) - ).transform[Int](_.map(_.toInt).getOrElse(-1), value => Some(value.toString)), + ).transform[Int](_.map(_.toInt).getOrElse(0), value => Some(value.toString)), "coveredSpaces" -> optional( text() .transform[String](_.strip().replaceAll(",", ""), identity) @@ -83,7 +82,7 @@ object HowManyParkingSpacesOrGaragesIncludedInRentForm extends CommonFormValidat isLargerThanInt(maxValue, coveredSpacesTooHighError) ) ) - ).transform[Int](_.map(_.toInt).getOrElse(-1), value => Some(value.toString)), + ).transform[Int](_.map(_.toInt).getOrElse(0), value => Some(value.toString)), "garages" -> optional( text() .transform[String](_.strip().replaceAll(",", ""), identity) @@ -93,7 +92,7 @@ object HowManyParkingSpacesOrGaragesIncludedInRentForm extends CommonFormValidat isLargerThanInt(maxValue, garagesTooHighError) ) ) - ).transform[Int](_.map(_.toInt).getOrElse(-1), value => Some(value.toString)), + ).transform[Int](_.map(_.toInt).getOrElse(0), value => Some(value.toString)), ) (HowManyParkingSpacesOrGaragesIncludedInRentForm.apply)(HowManyParkingSpacesOrGaragesIncludedInRentForm.unapply) .verifying( diff --git a/app/uk/gov/hmrc/ngrraldfrontend/models/forms/RepairsAndInsuranceForm.scala b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/RepairsAndInsuranceForm.scala new file mode 100644 index 00000000..e194f038 --- /dev/null +++ b/app/uk/gov/hmrc/ngrraldfrontend/models/forms/RepairsAndInsuranceForm.scala @@ -0,0 +1,79 @@ +/* + * 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.Form +import play.api.data.Forms.mapping +import play.api.i18n.* +import play.api.libs.json.{Json, OFormat} +import uk.gov.hmrc.govukfrontend.views.Aliases.Text +import uk.gov.hmrc.govukfrontend.views.viewmodels.fieldset.Legend +import uk.gov.hmrc.ngrraldfrontend.models.components.* +import uk.gov.hmrc.ngrraldfrontend.models.forms.DoesYourRentIncludeParkingForm.radioText +import uk.gov.hmrc.ngrraldfrontend.models.forms.mappings.Mappings + +final case class RepairsAndInsuranceForm( + internalRepairs: String, + externalRepairs: String, + buildingInsurance: String + ) + +object RepairsAndInsuranceForm extends CommonFormValidators with Mappings { + implicit val format: OFormat[RepairsAndInsuranceForm] = Json.format[RepairsAndInsuranceForm] + + private lazy val internalRepairsRequiredError = "repairsAndInsurance.internalRepairs.radio.required.error" + private lazy val externalRepairsRequiredError = "repairsAndInsurance.externalRepairs.radio.required.error" + private lazy val buildingInsuranceRequiredError = "repairsAndInsurance.buildingInsurance.radio.required.error" + private val internalRepairsRadio = "repairsAndInsurance-internalRepairs-radio-value" + private val externalRepairsRadio = "repairsAndInsurance-externalRepairs-radio-value" + private val buildingInsuranceRadio = "repairsAndInsurance-buildingInsurance-radio-value" + + val messagesApi: MessagesApi = new DefaultMessagesApi() + val lang: Lang = Lang.defaultLang + val messages: Messages = MessagesImpl(lang, messagesApi) + + def youButton(radioType: RadioEntry): NGRRadioButtons = NGRRadioButtons(radioContent = "repairsAndInsurance.radio.you", radioValue = radioType) + def landlordButton(radioType: RadioEntry): NGRRadioButtons = NGRRadioButtons(radioContent = "repairsAndInsurance.radio.landlord", radioValue = radioType) + def youAndLandlordButton(radioType: RadioEntry): NGRRadioButtons = NGRRadioButtons(radioContent = "repairsAndInsurance.radio.youAndLandlord", radioValue = radioType) + + def unapply(repairsAndInsuranceForm: RepairsAndInsuranceForm): Option[(String, String, String)] = + Some(repairsAndInsuranceForm.internalRepairs, repairsAndInsuranceForm.externalRepairs, repairsAndInsuranceForm.buildingInsurance) + + def ngrRadio(form: Form[RepairsAndInsuranceForm], radioType:String)(implicit messages: Messages): NGRRadio = { + val buttons: Seq[NGRRadioButtons] = radioType match { + case value if value.contains("internalRepairs") => Seq(youButton(InternalRepairsYou), landlordButton(InternalRepairsLandlord), youAndLandlordButton(InternalRepairsYouAndLandlord)) + case value if value.contains("externalRepairs") => Seq(youButton(ExternalRepairsYou), landlordButton(ExternalRepairsLandlord), youAndLandlordButton(ExternalRepairsYouAndLandlord)) + case _ => Seq(youButton(BuildingInsuranceYou), landlordButton(BuildingInsuranceLandlord), youAndLandlordButton(LandlordYouAndLandlord)) + } + NGRRadio( + NGRRadioName(s"repairsAndInsurance-$radioType-radio-value"), + ngrTitle = Some(Legend(content = Text(messages(s"repairsAndInsurance.$radioType.radio.label")), + classes = "govuk-fieldset__legend--m", isPageHeading = true)), + NGRRadioButtons = buttons + ) + } + + def form: Form[RepairsAndInsuranceForm] = { + Form( + mapping( + internalRepairsRadio -> radioText(internalRepairsRequiredError), + externalRepairsRadio -> radioText(externalRepairsRequiredError), + buildingInsuranceRadio -> radioText(buildingInsuranceRequiredError), + )(RepairsAndInsuranceForm.apply)(RepairsAndInsuranceForm.unapply) + ) + } +} diff --git a/app/uk/gov/hmrc/ngrraldfrontend/navigation/Navigator.scala b/app/uk/gov/hmrc/ngrraldfrontend/navigation/Navigator.scala index 5c2c3fa5..75bc502c 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/navigation/Navigator.scala +++ b/app/uk/gov/hmrc/ngrraldfrontend/navigation/Navigator.scala @@ -142,15 +142,15 @@ class Navigator @Inject()() { case None => uk.gov.hmrc.ngrraldfrontend.controllers.routes.CheckRentFreePeriodController.show(NormalMode) } case RentFreePeriodPage => _ => uk.gov.hmrc.ngrraldfrontend.controllers.routes.RentDatesAgreeStartController.show(NormalMode) - //TODO need to connect to next pages when they are done case DoYouPayExtraForParkingSpacesPage => answers => answers.get(DoYouPayExtraForParkingSpacesPage) match { case Some(value) => value match { case true => uk.gov.hmrc.ngrraldfrontend.controllers.routes.DoYouPayExtraForParkingSpacesController.show(NormalMode) - case _ => uk.gov.hmrc.ngrraldfrontend.controllers.routes.DoYouPayExtraForParkingSpacesController.show(NormalMode) + case _ => uk.gov.hmrc.ngrraldfrontend.controllers.routes.RepairsAndInsuranceController.show(NormalMode) } case None => throw new NotFoundException("Failed to find answers") } + case RepairsAndInsurancePage => _ => uk.gov.hmrc.ngrraldfrontend.controllers.routes.RentDatesAgreeStartController.show(NormalMode) //TODO Page not made yet } //TODO change to check your answers page diff --git a/app/uk/gov/hmrc/ngrraldfrontend/views/components/InputComponent.scala.html b/app/uk/gov/hmrc/ngrraldfrontend/pages/RepairsAndInsurancePage.scala similarity index 62% rename from app/uk/gov/hmrc/ngrraldfrontend/views/components/InputComponent.scala.html rename to app/uk/gov/hmrc/ngrraldfrontend/pages/RepairsAndInsurancePage.scala index 76463f28..fc5e6c7b 100644 --- a/app/uk/gov/hmrc/ngrraldfrontend/views/components/InputComponent.scala.html +++ b/app/uk/gov/hmrc/ngrraldfrontend/pages/RepairsAndInsurancePage.scala @@ -1,4 +1,4 @@ -@* +/* * Copyright 2025 HM Revenue & Customs * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,14 +12,18 @@ * 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.viewmodels.input.Input +package uk.gov.hmrc.ngrraldfrontend.pages -@this(govukInput : GovukInput) +import play.api.libs.json.JsPath +import uk.gov.hmrc.ngrraldfrontend.models.{HowManyParkingSpacesOrGarages, RepairsAndInsurance} -@(input: Input) +object RepairsAndInsurancePage extends QuestionPage[RepairsAndInsurance] { + override def toString: String = "repairsAndInsurance" + + override def path: JsPath = JsPath \ toString + +} -@govukInput(input) \ No newline at end of file diff --git a/app/uk/gov/hmrc/ngrraldfrontend/views/RepairsAndInsuranceView.scala.html b/app/uk/gov/hmrc/ngrraldfrontend/views/RepairsAndInsuranceView.scala.html new file mode 100644 index 00000000..39e728ac --- /dev/null +++ b/app/uk/gov/hmrc/ngrraldfrontend/views/RepairsAndInsuranceView.scala.html @@ -0,0 +1,46 @@ +@* + * 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.RepairsAndInsuranceForm + +@this( + layout: Layout, + govukRadios : GovukRadios, + formHelper: FormWithCSRF, + govukErrorSummary: GovukErrorSummary, + saveAndContinueButton: saveAndContinueButton +) + +@(form:Form[RepairsAndInsuranceForm], internalRepairs: Radios, externalRepairs: Radios, buildingInsurance: Radios, propertyAddress: String, mode: Mode)(implicit request: RequestHeader, messages: Messages, appConfig: AppConfig) + +@layout(pageTitle = Some(messages("repairsAndInsurance.title")), showBackLink = true, fullWidth = false) { + @formHelper(action = uk.gov.hmrc.ngrraldfrontend.controllers.routes.RepairsAndInsuranceController.submit(mode), Symbol("autoComplete") -> "off") { + @if(form.errors.nonEmpty) { + @govukErrorSummary(ErrorSummaryViewModel(form)) + } + @propertyAddress +

@messages("repairsAndInsurance.title")

+ @govukRadios(internalRepairs) + @govukRadios(externalRepairs) + @govukRadios(buildingInsurance) + @saveAndContinueButton(msg = messages("service.continue"), isStartButton = false) + } +} \ No newline at end of file diff --git a/conf/app.routes b/conf/app.routes index 864ba9cb..42065bb8 100644 --- a/conf/app.routes +++ b/conf/app.routes @@ -135,4 +135,10 @@ POST /rent-free-period/change uk.gov.hmrc.n GET /do-you-pay-extra-for-parking-spaces-or-garages-not-included-in-rent uk.gov.hmrc.ngrraldfrontend.controllers.DoYouPayExtraForParkingSpacesController.show(mode: Mode = NormalMode) POST /do-you-pay-extra-for-parking-spaces-or-garages-not-included-in-rent uk.gov.hmrc.ngrraldfrontend.controllers.DoYouPayExtraForParkingSpacesController.submit(mode: Mode = NormalMode) GET /do-you-pay-extra-for-parking-spaces-or-garages-not-included-in-rent/change uk.gov.hmrc.ngrraldfrontend.controllers.DoYouPayExtraForParkingSpacesController.show(mode: Mode = CheckMode) -POST /do-you-pay-extra-for-parking-spaces-or-garages-not-included-in-rent/change uk.gov.hmrc.ngrraldfrontend.controllers.DoYouPayExtraForParkingSpacesController.submit(mode: Mode = CheckMode) \ No newline at end of file +POST /do-you-pay-extra-for-parking-spaces-or-garages-not-included-in-rent/change uk.gov.hmrc.ngrraldfrontend.controllers.DoYouPayExtraForParkingSpacesController.submit(mode: Mode = CheckMode) + +#Repairs And Insurance +GET /repairs-and-insurance uk.gov.hmrc.ngrraldfrontend.controllers.RepairsAndInsuranceController.show(mode: Mode = NormalMode) +POST /repairs-and-insurance uk.gov.hmrc.ngrraldfrontend.controllers.RepairsAndInsuranceController.submit(mode: Mode = NormalMode) +GET /repairs-and-insurance/change uk.gov.hmrc.ngrraldfrontend.controllers.RepairsAndInsuranceController.show(mode: Mode = CheckMode) +POST /repairs-and-insurance/change uk.gov.hmrc.ngrraldfrontend.controllers.RepairsAndInsuranceController.submit(mode: Mode = CheckMode) \ No newline at end of file diff --git a/conf/messages b/conf/messages index 3cf1aabe..77da58f2 100644 --- a/conf/messages +++ b/conf/messages @@ -345,7 +345,6 @@ 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 howManyParkingSpacesOrGaragesIncludedInRent.coveredSpaces.wholeNum.error = Number of covered parking spaces included in your rent must be a number, like 9 howManyParkingSpacesOrGaragesIncludedInRent.garages.wholeNum.error = Number of garages included in your rent must be a number, like 9 @@ -386,4 +385,16 @@ rentFreePeriod.reasons.length.error = What you tell us about why you have a rent #DoYouPayExtraForParkingSpaces doYouPayExtraForParkingSpaces.title = Do you pay extra for parking spaces or garages that are not included in your rent? -doYouPayExtraForParkingSpaces.required.error = Select yes if your rent includes extra parking spaces or garages \ No newline at end of file +doYouPayExtraForParkingSpaces.required.error = Select yes if your rent includes extra parking spaces or garages + +#RepairsAndInsurance +repairsAndInsurance.title = Repairs and insurance +repairsAndInsurance.internalRepairs.radio.label = who pays for internal repairs? +repairsAndInsurance.externalRepairs.radio.label = who pays for external repairs? +repairsAndInsurance.buildingInsurance.radio.label = who pays for building insurance repairs? +repairsAndInsurance.radio.you = You +repairsAndInsurance.radio.landlord = The landlord +repairsAndInsurance.radio.youAndLandlord = You and the landlord +repairsAndInsurance.internalRepairs.radio.required.error = Select who pays for internal repairs +repairsAndInsurance.externalRepairs.radio.required.error = Select who pays for external repairs +repairsAndInsurance.buildingInsurance.radio.required.error = Select who pays for buildings insurance diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/AgreementControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/AgreementControllerSpec.scala index fb11f3d8..853d29cf 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/AgreementControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/AgreementControllerSpec.scala @@ -25,7 +25,7 @@ import uk.gov.hmrc.auth.core.Nino import uk.gov.hmrc.http.{HeaderNames, NotFoundException} import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement -import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, RaldUserAnswers, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId import uk.gov.hmrc.ngrraldfrontend.pages.{AgreedRentChangePage, AgreementPage} import uk.gov.hmrc.ngrraldfrontend.views.html.AgreementView diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/AgreementVerbalControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/AgreementVerbalControllerSpec.scala index 1d893e7f..5694bb20 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/AgreementVerbalControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/AgreementVerbalControllerSpec.scala @@ -27,7 +27,7 @@ import uk.gov.hmrc.http.{HeaderNames, NotFoundException} import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId -import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, RaldUserAnswers, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.pages.AgreementVerbalPage import uk.gov.hmrc.ngrraldfrontend.views.html.AgreementVerbalView import uk.gov.hmrc.ngrraldfrontend.views.html.components.DateTextFields diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/DidYouAgreeRentWithLandlordControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/DidYouAgreeRentWithLandlordControllerSpec.scala index 0c59d8b9..5c0e42b7 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/DidYouAgreeRentWithLandlordControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/DidYouAgreeRentWithLandlordControllerSpec.scala @@ -27,7 +27,7 @@ import uk.gov.hmrc.auth.core.Nino import uk.gov.hmrc.http.{HeaderNames, NotFoundException} import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement -import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, RaldUserAnswers, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId import uk.gov.hmrc.ngrraldfrontend.pages.DidYouAgreeRentWithLandlordPage import uk.gov.hmrc.ngrraldfrontend.views.html.DidYouAgreeRentWithLandlordView diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/DoYouPayExtraForParkingSpacesControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/DoYouPayExtraForParkingSpacesControllerSpec.scala index 735acdf8..81532a26 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/DoYouPayExtraForParkingSpacesControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/DoYouPayExtraForParkingSpacesControllerSpec.scala @@ -81,7 +81,7 @@ class DoYouPayExtraForParkingSpacesControllerSpec extends ControllerSpecSupport{ val result = controllerProperty(None).submit(NormalMode)(authenticatedFakePostRequest(fakePostRequest)) status(result) mustBe SEE_OTHER - redirectLocation(result) mustBe Some(routes.DoYouPayExtraForParkingSpacesController.show(NormalMode).url) + redirectLocation(result) mustBe Some(routes.RepairsAndInsuranceController.show(NormalMode).url) } "Return BAD_REQUEST for missing input and the correct view" in { val fakePostRequest = FakeRequest(routes.WhatTypeOfLeaseRenewalController.submit(NormalMode)) diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/DoesYourRentIncludeParkingControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/DoesYourRentIncludeParkingControllerSpec.scala index 8c98e3ea..b58a5637 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/DoesYourRentIncludeParkingControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/DoesYourRentIncludeParkingControllerSpec.scala @@ -27,7 +27,7 @@ import uk.gov.hmrc.http.{HeaderNames, NotFoundException} import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId -import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, RaldUserAnswers, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.pages.DoesYourRentIncludeParkingPage import uk.gov.hmrc.ngrraldfrontend.views.html.DoesYourRentIncludeParkingView diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentControllerSpec.scala index 4d2823a8..d5fea9cc 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/HowManyParkingSpacesOrGaragesIncludedInRentControllerSpec.scala @@ -28,7 +28,6 @@ import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId import uk.gov.hmrc.ngrraldfrontend.models.{HowManyParkingSpacesOrGarages, NormalMode, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.pages.HowManyParkingSpacesOrGaragesIncludedInRentPage import uk.gov.hmrc.ngrraldfrontend.views.html.HowManyParkingSpacesOrGaragesIncludedInRentView -import uk.gov.hmrc.ngrraldfrontend.views.html.components.InputText import scala.concurrent.Future @@ -53,7 +52,7 @@ class HowManyParkingSpacesOrGaragesIncludedInRentControllerSpec extends Controll navigator = mockNavigator, mcc = mcc)(mockConfig) - val howManyParkingGaragesAnswers: Option[UserAnswers] = UserAnswers("id").set(HowManyParkingSpacesOrGaragesIncludedInRentPage, HowManyParkingSpacesOrGarages("1","2","3")).toOption + val howManyParkingGaragesAnswers: Option[UserAnswers] = UserAnswers("id").set(HowManyParkingSpacesOrGaragesIncludedInRentPage, HowManyParkingSpacesOrGarages(1,2,3)).toOption "HowManyParkingSpacesOrGaragesIncludedInRentController" must { "method show" must { @@ -68,9 +67,9 @@ class HowManyParkingSpacesOrGaragesIncludedInRentControllerSpec extends Controll status(result) mustBe OK val content = contentAsString(result) val document = Jsoup.parse(content) - document.select("input[name=uncoveredSpaces]").attr("value") mustBe "1" - document.select("input[name=coveredSpaces]").attr("value") mustBe "2" - document.select("input[name=garages]").attr("value") mustBe "3" + document.select("input[name=uncoveredSpaces]").attr("value") mustEqual "1" + document.select("input[name=coveredSpaces]").attr("value") mustEqual "2" + document.select("input[name=garages]").attr("value") mustEqual "3" } "Return NotFoundException when property is not found in the mongo" in { when(mockNGRConnector.getLinkedProperty(any[CredId])(any())).thenReturn(Future.successful(None)) @@ -109,7 +108,7 @@ class HowManyParkingSpacesOrGaragesIncludedInRentControllerSpec extends Controll "Return Exception if no address is in the mongo" in { val fakePostRequest = FakeRequest(routes.HowManyParkingSpacesOrGaragesIncludedInRentController.submit(NormalMode)) .withFormUrlEncodedBody( - "uncoveredSpaces" -> "0", + "uncoveredSpaces" -> "", "coveredSpaces" -> "0", "garages" -> "0" ).withHeaders(HeaderNames.authorisation -> "Bearer 1") diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/LandlordControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/LandlordControllerSpec.scala index 590c2cea..1a0d6b4c 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/LandlordControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/LandlordControllerSpec.scala @@ -27,7 +27,7 @@ import uk.gov.hmrc.http.{HeaderNames, NotFoundException} import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.{NewAgreement, RenewedAgreement, RentAgreement} import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId -import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, RaldUserAnswers, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.pages.{LandlordPage, TellUsAboutRentPage, TellUsAboutYourNewAgreementPage, TellUsAboutYourRenewedAgreementPage} import uk.gov.hmrc.ngrraldfrontend.views.html.LandlordView import uk.gov.hmrc.ngrraldfrontend.views.html.components.NGRCharacterCountComponent diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/ProvideDetailsOfFirstSecondRentPeriodControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/ProvideDetailsOfFirstSecondRentPeriodControllerSpec.scala index 8ed59e4f..87be5909 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/ProvideDetailsOfFirstSecondRentPeriodControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/ProvideDetailsOfFirstSecondRentPeriodControllerSpec.scala @@ -27,7 +27,7 @@ import uk.gov.hmrc.auth.core.Nino import uk.gov.hmrc.http.{HeaderNames, NotFoundException} import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement -import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, RaldUserAnswers, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId import uk.gov.hmrc.ngrraldfrontend.pages.ProvideDetailsOfFirstSecondRentPeriodPage import uk.gov.hmrc.ngrraldfrontend.views.html.ProvideDetailsOfFirstSecondRentPeriodView diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentDatesAgreeControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentDatesAgreeControllerSpec.scala index 4057d032..a87b12af 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentDatesAgreeControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentDatesAgreeControllerSpec.scala @@ -26,7 +26,7 @@ import uk.gov.hmrc.auth.core.Nino import uk.gov.hmrc.http.{HeaderNames, NotFoundException} import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement -import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, RaldUserAnswers, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId import uk.gov.hmrc.ngrraldfrontend.pages.{AgreedRentChangePage, RentDatesAgreePage} import uk.gov.hmrc.ngrraldfrontend.views.html.RentDatesAgreeView diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentDatesAgreeStartControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentDatesAgreeStartControllerSpec.scala index 480789fd..8aeaf238 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentDatesAgreeStartControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentDatesAgreeStartControllerSpec.scala @@ -27,7 +27,7 @@ import uk.gov.hmrc.http.{HeaderNames, NotFoundException} import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId -import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, RaldUserAnswers, RentDatesAgreeStart, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, RentDatesAgreeStart, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.pages.RentDatesAgreeStartPage import uk.gov.hmrc.ngrraldfrontend.views.html.components.DateTextFields import uk.gov.hmrc.ngrraldfrontend.views.html.RentDatesAgreeStartView diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentPeriodsControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentPeriodsControllerSpec.scala index 1a9154ff..ec6f1e18 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentPeriodsControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/RentPeriodsControllerSpec.scala @@ -26,7 +26,7 @@ import uk.gov.hmrc.http.HeaderNames import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId -import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, ProvideDetailsOfFirstSecondRentPeriod, RaldUserAnswers, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, ProvideDetailsOfFirstSecondRentPeriod, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.pages.ProvideDetailsOfFirstSecondRentPeriodPage import uk.gov.hmrc.ngrraldfrontend.views.html.RentPeriodView diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/RepairsAndInsuranceControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/RepairsAndInsuranceControllerSpec.scala new file mode 100644 index 00000000..dc92b2c4 --- /dev/null +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/RepairsAndInsuranceControllerSpec.scala @@ -0,0 +1,133 @@ +/* + * 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 org.jsoup.Jsoup +import org.mockito.Mockito.when +import org.mockito.ArgumentMatchers.any +import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport +import uk.gov.hmrc.ngrraldfrontend.views.html.RepairsAndInsuranceView +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.models.registration.CredId +import uk.gov.hmrc.ngrraldfrontend.models.{NormalMode, RepairsAndInsurance, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.pages.RepairsAndInsurancePage + +import scala.concurrent.Future + +class RepairsAndInsuranceControllerSpec extends ControllerSpecSupport { + val pageTitle = "Repairs and insurance" + + val view: RepairsAndInsuranceView = inject[RepairsAndInsuranceView] + val controller: RepairsAndInsuranceController = new RepairsAndInsuranceController( + repairsAndInsuranceView = view, + authenticate = fakeAuth, + navigator = mockNavigator, + getData = fakeData(None), + sessionRepository = mockSessionRepository, + mcc = mcc)(mockConfig) + + val controllerProperty: Option[UserAnswers] => RepairsAndInsuranceController = answers => new RepairsAndInsuranceController( + repairsAndInsuranceView = view, + authenticate = fakeAuth, + navigator = mockNavigator, + getData = fakeDataProperty(Some(property), answers), + sessionRepository = mockSessionRepository, + mcc = mcc)(mockConfig) + + val repairsAndInsuranceAnswers = UserAnswers("id").set(RepairsAndInsurancePage, repairsAndInsuranceModel).toOption + + "RepairsAndInsuranceController" must { + "method show" must { + "Return OK and the correct view" in { + val result = controllerProperty(None).show(NormalMode)(authenticatedFakeRequest) + status(result) mustBe OK + val content = contentAsString(result) + content must include(pageTitle) + } + "return OK and the correct view with prepopulated answers" in { + val result = controllerProperty(repairsAndInsuranceAnswers).show(NormalMode)(authenticatedFakeRequest) + status(result) mustBe OK + val content = contentAsString(result) + val document = Jsoup.parse(content) + document.select("input[name=repairsAndInsurance-internalRepairs-radio-value]").attr("value") mustEqual "InternalRepairsYou" + document.select("input[name=repairsAndInsurance-externalRepairs-radio-value]").attr("value") mustEqual "ExternalRepairsYou" + document.select("input[name=repairsAndInsurance-buildingInsurance-radio-value]").attr("value") mustEqual "BuildingInsuranceYou" + } + "Return NotFoundException when property is not found in the mongo" in { + when(mockNGRConnector.getLinkedProperty(any[CredId])(any())).thenReturn(Future.successful(None)) + val exception = intercept[NotFoundException] { + await(controller.show(NormalMode)(authenticatedFakeRequest)) + } + exception.getMessage contains "Could not find answers in backend mongo" mustBe true + } + } + "method submit" must { + "Return OK and the correct view" in { + when(mockSessionRepository.set(any())).thenReturn(Future.successful(true)) + val fakePostRequest = FakeRequest(routes.RepairsAndInsuranceController.submit(NormalMode)) + .withFormUrlEncodedBody( + "repairsAndInsurance-internalRepairs-radio-value" -> "InternalRepairsYou", + "repairsAndInsurance-externalRepairs-radio-value" -> "ExternalRepairsYou", + "repairsAndInsurance-buildingInsurance-radio-value" -> "BuildingInsuranceYou" + ).withHeaders(HeaderNames.authorisation -> "Bearer 1") + + val result = controllerProperty(None).submit(NormalMode)(authenticatedFakePostRequest(fakePostRequest)) + status(result) mustBe SEE_OTHER + redirectLocation(result) mustBe Some(routes.RentDatesAgreeStartController.show(NormalMode).url) + } + "Return BAD_REQUEST for not selecting a internal repairs radio, showing the correct view and error" in { + val fakePostRequest = FakeRequest(routes.RepairsAndInsuranceController.submit(NormalMode)) + .withFormUrlEncodedBody( + "repairsAndInsurance-internalRepairs-radio-value" -> "", + "repairsAndInsurance-externalRepairs-radio-value" -> "ExternalRepairsYou", + "repairsAndInsurance-buildingInsurance-radio-value" -> "BuildingInsuranceYou" + ).withHeaders(HeaderNames.authorisation -> "Bearer 1") + val result = controllerProperty(None).submit(NormalMode)(authenticatedFakePostRequest(fakePostRequest)) + status(result) mustBe BAD_REQUEST + val content = contentAsString(result) + content must include("Select who pays for internal repairs") + } + "Return BAD_REQUEST for not selecting a external repairs radio, showing the correct view and error" in { + val fakePostRequest = FakeRequest(routes.RepairsAndInsuranceController.submit(NormalMode)) + .withFormUrlEncodedBody( + "repairsAndInsurance-internalRepairs-radio-value" -> "InternalRepairsYou", + "repairsAndInsurance-externalRepairs-radio-value" -> "", + "repairsAndInsurance-buildingInsurance-radio-value" -> "BuildingInsuranceYou" + ).withHeaders(HeaderNames.authorisation -> "Bearer 1") + val result = controllerProperty(None).submit(NormalMode)(authenticatedFakePostRequest(fakePostRequest)) + status(result) mustBe BAD_REQUEST + val content = contentAsString(result) + content must include("Select who pays for external repairs") + } + "Return BAD_REQUEST for not selecting a building insurance radio, showing the correct view and error" in { + val fakePostRequest = FakeRequest(routes.RepairsAndInsuranceController.submit(NormalMode)) + .withFormUrlEncodedBody( + "repairsAndInsurance-internalRepairs-radio-value" -> "InternalRepairsYou", + "repairsAndInsurance-externalRepairs-radio-value" -> "ExternalRepairsYou", + "repairsAndInsurance-buildingInsurance-radio-value" -> "" + ).withHeaders(HeaderNames.authorisation -> "Bearer 1") + val result = controllerProperty(None).submit(NormalMode)(authenticatedFakePostRequest(fakePostRequest)) + status(result) mustBe BAD_REQUEST + val content = contentAsString(result) + content must include("Select who pays for buildings insurance") + } + } + } +} diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/TellUsAboutYourNewAgreementControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/TellUsAboutYourNewAgreementControllerSpec.scala index b08b3048..1d8d76ea 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/TellUsAboutYourNewAgreementControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/TellUsAboutYourNewAgreementControllerSpec.scala @@ -25,7 +25,7 @@ import uk.gov.hmrc.http.NotFoundException import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId -import uk.gov.hmrc.ngrraldfrontend.models.{NormalMode, RaldUserAnswers, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{NormalMode, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.views.html.TellUsAboutYourAgreementView import scala.concurrent.Future diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/WhatIsYourRentBasedOnControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/WhatIsYourRentBasedOnControllerSpec.scala index 7b6c6855..231abea6 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/WhatIsYourRentBasedOnControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/WhatIsYourRentBasedOnControllerSpec.scala @@ -27,7 +27,7 @@ import uk.gov.hmrc.http.{HeaderNames, NotFoundException} import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId -import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, RaldUserAnswers, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.pages.WhatIsYourRentBasedOnPage import uk.gov.hmrc.ngrraldfrontend.views.html.WhatIsYourRentBasedOnView import uk.gov.hmrc.ngrraldfrontend.views.html.components.NGRCharacterCountComponent diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/WhatTypeOfAgreementControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/WhatTypeOfAgreementControllerSpec.scala index dea9cad2..86765995 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/WhatTypeOfAgreementControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/WhatTypeOfAgreementControllerSpec.scala @@ -28,7 +28,7 @@ import uk.gov.hmrc.http.{HeaderNames, NotFoundException} import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId -import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, RaldUserAnswers, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.pages.WhatTypeOfAgreementPage import uk.gov.hmrc.ngrraldfrontend.views.html.WhatTypeOfAgreementView diff --git a/test/uk/gov/hmrc/ngrraldfrontend/controllers/WhatYourRentIncludesControllerSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/controllers/WhatYourRentIncludesControllerSpec.scala index 415a191b..8b55d60d 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/controllers/WhatYourRentIncludesControllerSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/controllers/WhatYourRentIncludesControllerSpec.scala @@ -26,7 +26,7 @@ import uk.gov.hmrc.auth.core.Nino import uk.gov.hmrc.http.{HeaderNames, NotFoundException} import uk.gov.hmrc.ngrraldfrontend.helpers.ControllerSpecSupport import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement -import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, RaldUserAnswers, UserAnswers} +import uk.gov.hmrc.ngrraldfrontend.models.{AuthenticatedUserRequest, NormalMode, UserAnswers} import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId import uk.gov.hmrc.ngrraldfrontend.pages.WhatYourRentIncludesPage import uk.gov.hmrc.ngrraldfrontend.views.html.WhatYourRentIncludesView diff --git a/test/uk/gov/hmrc/ngrraldfrontend/helpers/TestData.scala b/test/uk/gov/hmrc/ngrraldfrontend/helpers/TestData.scala index d47fb12a..c62019b9 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/helpers/TestData.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/helpers/TestData.scala @@ -149,4 +149,6 @@ trait TestData { val whatYourRentIncludesModelAllNo: WhatYourRentIncludes = WhatYourRentIncludes(false,false,false,false,false,false,None) val rentBasedOnModel: RentBasedOn = RentBasedOn("Other",Some("The rent was agreed")) + + val repairsAndInsuranceModel = RepairsAndInsurance("internalRepairs", "externalRepairs", "buildingInsurance") } \ No newline at end of file diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/PageSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/PageSpec.scala new file mode 100644 index 00000000..7af14836 --- /dev/null +++ b/test/uk/gov/hmrc/ngrraldfrontend/models/PageSpec.scala @@ -0,0 +1,33 @@ +/* + * 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 org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers +import uk.gov.hmrc.ngrraldfrontend.pages.Page + +class TestPage extends Page { + override def toString: String = "TestPage" +} + +class PageSpec extends AnyFlatSpec with Matchers { + "Page.toString" should "implicitly convert Page to String using toString" in { + val page: Page = new TestPage + val str: String = page // implicit conversion + str shouldEqual "TestPage" + } +} diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswersSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswersSpec.scala deleted file mode 100644 index 24fea825..00000000 --- a/test/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswersSpec.scala +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 org.scalatest.matchers.must.Matchers -import org.scalatest.matchers.should.Matchers.shouldBe -import org.scalatest.wordspec.AnyWordSpec -import play.api.libs.json.{Json, OFormat} -import uk.gov.hmrc.ngrraldfrontend.helpers.TestData -import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.NewAgreement -import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId -import uk.gov.hmrc.ngrraldfrontend.models.vmvProperty.VMVProperty - -class RaldUserAnswersSpec extends AnyWordSpec with Matchers with TestData { - implicit val credIdFormat: OFormat[CredId] = Json.format[CredId] - implicit val vmvPropertyFormat: OFormat[VMVProperty] = Json.format[VMVProperty] - implicit val currentRatepayerFormat: OFormat[CurrentRatepayer] = Json.format[CurrentRatepayer] - "RaldUserAnswers" should { - "serialize to JSON" in { - val answers = RaldUserAnswers( - credId = CredId("cred123"), - agreementType = NewAgreement, - selectedProperty = property, - whatTypeOfAgreement = None - ) - - val json = Json.toJson(answers) - - (json \ "credId" \ "value").as[String] shouldBe "cred123" - (json \ "selectedProperty" \ "localAuthorityReference").as[String] shouldBe property.localAuthorityReference - } - - "deserialize from JSON" in { - val json = Json.parse( - """ - |{ - | "credId" : { - | "value" : "9900000000000101" - | }, - | "agreementType" : "NewAgreement", - | "selectedProperty" : { - | "localAuthorityReference" : "2191322564521", - | "valuations" : [ - | { - | "descriptionText" : "GOLF", - | "rateableValue" : 109300, - | "assessmentRef" : 85141561000, - | "scatCode" : "249", - | "currentFromDate" : "2023-04-01", - | "effectiveDate" : "2023-04-01", - | "listYear" : "2023", - | "propertyLinkEarliestStartDate" : "2017-04-01", - | "primaryDescription" : "CS", - | "listType" : "current", - | "assessmentStatus" : "CURRENT", - | "allowedActions" : [ - | "check", - | "challenge", - | "viewDetailedValuation", - | "propertyLink", - | "similarProperties" - | ] - | } - | ], - | "addressFull" : "A, RODLEY LANE, RODLEY, LEEDS, BH1 7EY", - | "localAuthorityCode" : "4720", - | "uarn" : 11905603000 - | } - |} - |""".stripMargin) - - val result = json.as[RaldUserAnswers] - - result.credId shouldBe CredId("9900000000000101") - result.selectedProperty shouldBe property - } - } -} diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/RepairsAndInsuranceSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/RepairsAndInsuranceSpec.scala new file mode 100644 index 00000000..a9ce002d --- /dev/null +++ b/test/uk/gov/hmrc/ngrraldfrontend/models/RepairsAndInsuranceSpec.scala @@ -0,0 +1,71 @@ +/* + * 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 org.scalatest.wordspec.AnyWordSpec +import org.scalatest.matchers.should.Matchers +import play.api.libs.json._ + +class RepairsAndInsuranceSpec extends AnyWordSpec with Matchers { + + "RepairsAndInsurance JSON format" should { + + "serialize to JSON correctly" in { + val model = RepairsAndInsurance( + internalRepairs = "You", + externalRepairs = "The landlord", + buildingInsurance = "You and the landlord" + ) + + val expectedJson = Json.obj( + "internalRepairs" -> "You", + "externalRepairs" -> "The landlord", + "buildingInsurance" -> "You and the landlord" + ) + + Json.toJson(model) shouldBe expectedJson + } + + "deserialize from JSON correctly" in { + val json = Json.obj( + "internalRepairs" -> "You", + "externalRepairs" -> "The landlord", + "buildingInsurance" -> "You and the landlord" + ) + + val expectedModel = RepairsAndInsurance( + internalRepairs = "You", + externalRepairs = "The landlord", + buildingInsurance = "You and the landlord" + ) + + json.as[RepairsAndInsurance] shouldBe expectedModel + } + + "fail to deserialize if a field is missing" in { + val incompleteJson = Json.obj( + "internalRepairs" -> "You", + "externalRepairs" -> "The landlord" + ) + + assertThrows[JsResultException] { + incompleteJson.as[RepairsAndInsurance] + } + } + } +} + diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/VMVPropertySpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/VMVPropertySpec.scala new file mode 100644 index 00000000..72b03da8 --- /dev/null +++ b/test/uk/gov/hmrc/ngrraldfrontend/models/VMVPropertySpec.scala @@ -0,0 +1,53 @@ +/* + * 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 org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers +import play.api.libs.json.* +import uk.gov.hmrc.ngrraldfrontend.helpers.TestData +import uk.gov.hmrc.ngrraldfrontend.models.vmvProperty.{VMVProperty, Valuation} + +class VMVPropertySpec extends AnyFlatSpec with Matchers with TestData { + + "VMVProperty JSON format" should "serialize and deserialize correctly" in { + + val json = Json.toJson(property) + val expectedJson = Json.parse( + """ + { + "uarn":11905603000, + "addressFull":"A, RODLEY LANE, RODLEY, LEEDS, BH1 7EY", + "localAuthorityCode":"4720", + "localAuthorityReference":"2191322564521", + "valuations":[{ + "assessmentRef":85141561000,"assessmentStatus":"CURRENT","rateableValue":109300,"scatCode":"249","descriptionText":"GOLF","effectiveDate":"2023-04-01","currentFromDate":"2023-04-01","listYear":"2023","primaryDescription":"CS","allowedActions":["check","challenge","viewDetailedValuation","propertyLink","similarProperties"],"listType":"current","propertyLinkEarliestStartDate":"2017-04-01"} + ]} + """ + ) + + json shouldEqual expectedJson + json.validate[VMVProperty] shouldEqual JsSuccess(property) + } + + it should "fail to deserialize invalid JSON" in { + val invalidJson = Json.parse("""{ "uarn": "not-a-long" }""") + invalidJson.validate[VMVProperty] shouldBe a[JsError] + } +} + diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/HowManyParkingSpacesOrGaragesIncludedInRentFormSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/HowManyParkingSpacesOrGaragesIncludedInRentFormSpec.scala index 89c88be4..229a6c6e 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/HowManyParkingSpacesOrGaragesIncludedInRentFormSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/HowManyParkingSpacesOrGaragesIncludedInRentFormSpec.scala @@ -39,14 +39,37 @@ class HowManyParkingSpacesOrGaragesIncludedInRentFormSpec extends AnyWordSpec wi boundForm.value shouldBe Some(HowManyParkingSpacesOrGaragesIncludedInRentForm(uncoveredSpaces = 100, coveredSpaces = 100, garages = 100)) } - "bind empty input" in { + "bind with 2 empty inputs" in { val data = Map( "uncoveredSpaces" -> "", - "coveredSpaces" -> "100", - "garages" -> "100" + "coveredSpaces" -> "1", + "garages" -> "" ) val boundForm = HowManyParkingSpacesOrGaragesIncludedInRentForm.form.bind(data) boundForm.hasErrors shouldBe false + boundForm.errors shouldBe List() + } + + "bind with 1 empty input" in { + val data = Map( + "uncoveredSpaces" -> "1", + "coveredSpaces" -> "1", + "garages" -> "" + ) + val boundForm = HowManyParkingSpacesOrGaragesIncludedInRentForm.form.bind(data) + boundForm.hasErrors shouldBe false + boundForm.errors shouldBe List() + } + + "fail to bind with 3 empty input" in { + val data = Map( + "uncoveredSpaces" -> "", + "coveredSpaces" -> "", + "garages" -> "" + ) + val boundForm = HowManyParkingSpacesOrGaragesIncludedInRentForm.form.bind(data) + boundForm.hasErrors shouldBe true + boundForm.errors shouldBe List(FormError("", "howManyParkingSpacesOrGaragesIncludedInRent.error.required")) } "bind field with commas input" in { @@ -115,7 +138,7 @@ class HowManyParkingSpacesOrGaragesIncludedInRentFormSpec extends AnyWordSpec wi val boundForm = HowManyParkingSpacesOrGaragesIncludedInRentForm.form.bind(data) boundForm.hasErrors shouldBe true - boundForm.errors shouldBe List(FormError("", "howManyParkingSpacesOrGaragesIncludedInRent.allFields.error.required")) + boundForm.errors shouldBe List(FormError("", "howManyParkingSpacesOrGaragesIncludedInRent.error.required")) } "fail to bind when input fields are all 0" in { @@ -163,7 +186,7 @@ class HowManyParkingSpacesOrGaragesIncludedInRentFormSpec extends AnyWordSpec wi val result = json.validate[HowManyParkingSpacesOrGaragesIncludedInRentForm] result.isSuccess shouldBe true - result.get shouldBe HowManyParkingSpacesOrGaragesIncludedInRentForm(10,10,10) + result.get shouldBe HowManyParkingSpacesOrGaragesIncludedInRentForm(10, 10, 10) } "fail deserialization if value is missing" in { diff --git a/test/uk/gov/hmrc/ngrraldfrontend/models/forms/RepairsAndInsuranceFormSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/RepairsAndInsuranceFormSpec.scala new file mode 100644 index 00000000..32ac273c --- /dev/null +++ b/test/uk/gov/hmrc/ngrraldfrontend/models/forms/RepairsAndInsuranceFormSpec.scala @@ -0,0 +1,65 @@ +/* + * 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 org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers +import play.api.data.FormError + +class RepairsAndInsuranceFormSpec extends AnyFlatSpec with Matchers { + + val validData = Map( + "repairsAndInsurance-internalRepairs-radio-value" -> "InternalRepairsYou", + "repairsAndInsurance-externalRepairs-radio-value" -> "ExternalRepairsYou", + "repairsAndInsurance-buildingInsurance-radio-value" -> "BuildingInsuranceYou" + ) + + "RepairsAndInsuranceForm" should "bind valid data successfully" in { + val boundForm = RepairsAndInsuranceForm.form.bind(validData) + boundForm.errors shouldBe empty + boundForm.value shouldBe Some(RepairsAndInsuranceForm("InternalRepairsYou", "ExternalRepairsYou", "BuildingInsuranceYou")) + } + + it should "fail when internal repairs radio input is missing" in { + val data = validData - "repairsAndInsurance-internalRepairs-radio-value" + val boundForm = RepairsAndInsuranceForm.form.bind(data) + + boundForm.errors shouldBe List(FormError("repairsAndInsurance-internalRepairs-radio-value", List("repairsAndInsurance.internalRepairs.radio.required.error"), List())) + } + + it should "fail when external repairs radio input is missing" in { + val data = validData - "repairsAndInsurance-externalRepairs-radio-value" + val boundForm = RepairsAndInsuranceForm.form.bind(data) + + boundForm.errors shouldBe List(FormError("repairsAndInsurance-externalRepairs-radio-value", List("repairsAndInsurance.externalRepairs.radio.required.error"), List())) + } + + it should "fail when building insurance radio input is missing" in { + val data = validData - "repairsAndInsurance-buildingInsurance-radio-value" + val boundForm = RepairsAndInsuranceForm.form.bind(data) + + boundForm.errors shouldBe List(FormError("repairsAndInsurance-buildingInsurance-radio-value", List("repairsAndInsurance.buildingInsurance.radio.required.error"), List())) + } + + "RentPeriods.unapply" should "extract fields correctly" in { + val form = RepairsAndInsuranceForm("InternalRepairsYou", "ExternalRepairsYou", "BuildingInsuranceYou") + val result = RepairsAndInsuranceForm.unapply(form) + result shouldBe Some("InternalRepairsYou", "ExternalRepairsYou", "BuildingInsuranceYou") + } + +} + diff --git a/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepoSpec.scala deleted file mode 100644 index e69de29b..00000000 diff --git a/test/uk/gov/hmrc/ngrraldfrontend/views/HowManyParkingSpacesOrGaragesIncludedInRentViewSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/views/HowManyParkingSpacesOrGaragesIncludedInRentViewSpec.scala index e48e94b7..e276a6a0 100644 --- a/test/uk/gov/hmrc/ngrraldfrontend/views/HowManyParkingSpacesOrGaragesIncludedInRentViewSpec.scala +++ b/test/uk/gov/hmrc/ngrraldfrontend/views/HowManyParkingSpacesOrGaragesIncludedInRentViewSpec.scala @@ -50,7 +50,7 @@ class HowManyParkingSpacesOrGaragesIncludedInRentViewSpec extends ViewBaseSpec { val address = "5 Brixham Marina, Berry Head Road, Brixham, Devon, TQ5 9BW" - val form = HowManyParkingSpacesOrGaragesIncludedInRentForm.form.fillAndValidate(HowManyParkingSpacesOrGaragesIncludedInRentForm(10000,0,0)) + val form = HowManyParkingSpacesOrGaragesIncludedInRentForm.form.fillAndValidate(HowManyParkingSpacesOrGaragesIncludedInRentForm(10000, 0, 0)) val mockInputText: InputText = inject[InputText] def generateInputText(form: Form[HowManyParkingSpacesOrGaragesIncludedInRentForm], inputFieldName: String)(implicit messages: Messages): HtmlFormat.Appendable = { mockInputText( diff --git a/test/uk/gov/hmrc/ngrraldfrontend/views/RepairsAndInsuranceViewSpec.scala b/test/uk/gov/hmrc/ngrraldfrontend/views/RepairsAndInsuranceViewSpec.scala new file mode 100644 index 00000000..2a5fb756 --- /dev/null +++ b/test/uk/gov/hmrc/ngrraldfrontend/views/RepairsAndInsuranceViewSpec.scala @@ -0,0 +1,120 @@ +/* + * 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 +import org.jsoup.nodes.Document +import play.api.data.Form +import play.api.i18n.Messages +import uk.gov.hmrc.govukfrontend.views.Aliases.Text +import uk.gov.hmrc.govukfrontend.views.viewmodels.fieldset.Legend +import uk.gov.hmrc.govukfrontend.views.viewmodels.radios.Radios +import uk.gov.hmrc.ngrraldfrontend.helpers.ViewBaseSpec +import uk.gov.hmrc.ngrraldfrontend.models.{AgreementType, NormalMode} +import uk.gov.hmrc.ngrraldfrontend.models.components.NGRRadio.buildRadios +import uk.gov.hmrc.ngrraldfrontend.models.components.{BuildingInsuranceLandlord, BuildingInsuranceYou, ExternalRepairsLandlord, ExternalRepairsYou, ExternalRepairsYouAndLandlord, InternalRepairsLandlord, InternalRepairsYou, InternalRepairsYouAndLandlord, LandlordYouAndLandlord, NGRRadio, NGRRadioButtons, NGRRadioName} +import uk.gov.hmrc.ngrraldfrontend.models.forms.RepairsAndInsuranceForm +import uk.gov.hmrc.ngrraldfrontend.models.forms.RepairsAndInsuranceForm.{form, landlordButton, youAndLandlordButton, youButton} +import uk.gov.hmrc.ngrraldfrontend.views.html.RepairsAndInsuranceView + +class RepairsAndInsuranceViewSpec extends ViewBaseSpec { + lazy val view: RepairsAndInsuranceView = inject[RepairsAndInsuranceView] + + object Strings { + val heading = "Repairs and insurance" + val internalRepairslabel = "who pays for internal repairs?" + val externalRepairslabel = "who pays for external repairs?" + val buildingInsurancelabel = "who pays for building insurance repairs?" + val continue = "Continue" + } + + object Selectors { + val heading = "#main-content > div > div.govuk-grid-column-two-thirds > form > h1" + val internalRepairslabel = "#main-content > div > div.govuk-grid-column-two-thirds > form > div:nth-child(3) > fieldset > legend > h1" + val externalRepairslabel = "#main-content > div > div.govuk-grid-column-two-thirds > form > div:nth-child(4) > fieldset > legend > h1" + val buildingInsurancelabel = "#main-content > div > div.govuk-grid-column-two-thirds > form > div:nth-child(5) > fieldset > legend > h1" + val continue = "#continue" + } + + val address = "5 Brixham Marina, Berry Head Road, Brixham, Devon, TQ5 9BW" + val form = RepairsAndInsuranceForm.form.fillAndValidate( + RepairsAndInsuranceForm( + "InternalRepairsYou", + "ExternalRepairsYou", + "BuildingInsuranceYou" + ) + ) + + def ngrRadio(form: Form[RepairsAndInsuranceForm], radioType:String)(implicit messages: Messages): NGRRadio = { + val buttons: Seq[NGRRadioButtons] = radioType match { + case value if value.contains("internalRepairs") => Seq(youButton(InternalRepairsYou), landlordButton(InternalRepairsLandlord), youAndLandlordButton(InternalRepairsYouAndLandlord)) + case value if value.contains("externalRepairs") => Seq(youButton(ExternalRepairsYou), landlordButton(ExternalRepairsLandlord), youAndLandlordButton(ExternalRepairsYouAndLandlord)) + case _ => Seq(youButton(BuildingInsuranceYou), landlordButton(BuildingInsuranceLandlord), youAndLandlordButton(LandlordYouAndLandlord)) + } + NGRRadio( + NGRRadioName(s"repairsAndInsurance-$radioType-radio-value"), + ngrTitle = Some(Legend(content = Text(messages(s"repairsAndInsurance.$radioType.radio.label")), + classes = "govuk-fieldset__legend--l", isPageHeading = true)), + NGRRadioButtons = buttons + ) + } + + val internalRepairs: Radios = buildRadios(form, RepairsAndInsuranceForm.ngrRadio(form, "internalRepairs")) + val externalRepairs: Radios = buildRadios(form, RepairsAndInsuranceForm.ngrRadio(form, "externalRepairs")) + val buildingInsurance: Radios = buildRadios(form, RepairsAndInsuranceForm.ngrRadio(form, "buildingInsurance")) + + "RepairsAndInsuranceView" must { + val repairsAndInsuranceView = view(form,internalRepairs, externalRepairs, buildingInsurance, address, NormalMode) + lazy implicit val document: Document = Jsoup.parse(repairsAndInsuranceView.body) + val htmlApply = view.apply(form, internalRepairs, externalRepairs, buildingInsurance, address, NormalMode).body + val htmlRender = view.render(form,internalRepairs, externalRepairs, buildingInsurance, address, NormalMode, request, messages, mockConfig).body + lazy val htmlF = view.f(form,internalRepairs, externalRepairs, buildingInsurance, address, NormalMode) + + "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 internal Repairs label" in { + elementText(Selectors.internalRepairslabel) mustBe Strings.internalRepairslabel + } + + "show correct external Repairs label" in { + elementText(Selectors.externalRepairslabel) mustBe Strings.externalRepairslabel + } + + "show correct building Insurance label" in { + elementText(Selectors.buildingInsurancelabel) mustBe Strings.buildingInsurancelabel + } + + "show correct continue button" in { + elementText(Selectors.continue) mustBe Strings.continue + } + } +} +