Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* 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.http.NotFoundException
import uk.gov.hmrc.ngrraldfrontend.actions.{AuthRetrievals, PropertyLinkingAction}
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.components.NavBarPageContents.createDefaultNavBar
import uk.gov.hmrc.ngrraldfrontend.models.forms.DidYouAgreeRentWithLandlordForm
import uk.gov.hmrc.ngrraldfrontend.models.forms.DidYouAgreeRentWithLandlordForm.form
import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId
import uk.gov.hmrc.ngrraldfrontend.repo.RaldRepo
import uk.gov.hmrc.ngrraldfrontend.views.html.DidYouAgreeRentWithLandlordView
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendController

import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}

@Singleton
class DidYouAgreeRentWithLandlordController @Inject()(didYouAgreeRentWithLandlordView: DidYouAgreeRentWithLandlordView,
authenticate: AuthRetrievals,
hasLinkedProperties: PropertyLinkingAction,
raldRepo: RaldRepo,
mcc: MessagesControllerComponents)(implicit appConfig: AppConfig, ec: ExecutionContext)
extends FrontendController(mcc) with I18nSupport {


def show: Action[AnyContent] = {
(authenticate andThen hasLinkedProperties).async { implicit request =>
request.propertyLinking.map(property =>
Future.successful(Ok(didYouAgreeRentWithLandlordView(
selectedPropertyAddress = property.addressFull,
navigationBarContent = createDefaultNavBar,
form = form,
ngrRadio = buildRadios(form, DidYouAgreeRentWithLandlordForm.ngrRadio(form)),
)))).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(didYouAgreeRentWithLandlordView(
form = formWithErrors,
navigationBarContent = createDefaultNavBar,
ngrRadio = buildRadios(formWithErrors, DidYouAgreeRentWithLandlordForm.ngrRadio(formWithErrors)),
selectedPropertyAddress = property.addressFull
)))).getOrElse(throw new NotFoundException("Couldn't find property in mongo"))
},
radioValue =>
raldRepo.insertDidYouAgreeRentWithLandlord(
credId = CredId(request.credId.getOrElse("")),
radioValue = radioValue.toString
)
if(radioValue.radioValue.toString == "YesTheLandlord"){
Future.successful(Redirect(routes.CheckRentFreePeriodController.show.url))
}else{
//TODO
Future.successful(Redirect(routes.CheckRentFreePeriodController.show.url))
}

)
}
}
5 changes: 3 additions & 2 deletions app/uk/gov/hmrc/ngrraldfrontend/models/RaldUserAnswers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ final case class RaldUserAnswers(
agreedRentChange: Option[String] = None,
agreementVerbal: Option[AgreementVerbal] = None,
hasRentFreePeriod: Option[Boolean] = None,
agreement: Option[Agreement] = None,
provideDetailsOfFirstSecondRentPeriod: Option[ProvideDetailsOfFirstSecondRentPeriod] = None
agreement: Option[Agreement] = None,
provideDetailsOfFirstSecondRentPeriod: Option[ProvideDetailsOfFirstSecondRentPeriod] = None,
didYouAgreeRentWithLandlord: Option[Boolean] = None
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ sealed trait firstRentPeriod extends RadioEntry
case object yesPayedRent extends RadioEntry
case object noRentPayed extends RadioEntry

sealed trait DidYouAgreeRentWithLandlord extends RadioEntry
case object YesTheLandlord extends DidYouAgreeRentWithLandlord
case object NoACourtSet extends DidYouAgreeRentWithLandlord

case class NGRRadioName(key: String)

case class NGRRadioButtons(radioContent: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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.Messages
import play.api.libs.json.{Json, OFormat}
import uk.gov.hmrc.ngrraldfrontend.models.components.*
import uk.gov.hmrc.ngrraldfrontend.models.forms.mappings.Mappings

final case class DidYouAgreeRentWithLandlordForm (radioValue: String)

object DidYouAgreeRentWithLandlordForm extends Mappings {
implicit val format: OFormat[DidYouAgreeRentWithLandlordForm] = Json.format[DidYouAgreeRentWithLandlordForm]

private lazy val radioUnselectedError = "didYouAgreeRentWithLandlord.error.required"
private val didYouAgreeRentWithLandlordRadio = "did-you-agree-rent-with-landlord-radio"

def unapply(didYouAgreeRentWithLandlordForm: DidYouAgreeRentWithLandlordForm): Option[String] = Some(didYouAgreeRentWithLandlordForm.radioValue)

def form: Form[DidYouAgreeRentWithLandlordForm] = {
Form(
mapping(
didYouAgreeRentWithLandlordRadio -> text(radioUnselectedError)
)(DidYouAgreeRentWithLandlordForm.apply)(DidYouAgreeRentWithLandlordForm.unapply)
)
}

private val yes: NGRRadioButtons = NGRRadioButtons(radioContent = "didYouAgreeRentWithLandlord.yes", radioValue = YesTheLandlord)
private val no: NGRRadioButtons = NGRRadioButtons(radioContent = "didYouAgreeRentWithLandlord.no", radioValue = NoACourtSet)

def ngrRadio(form: Form[DidYouAgreeRentWithLandlordForm])(implicit messages: Messages): NGRRadio =
NGRRadio(NGRRadioName("did-you-agree-rent-with-landlord-radio"),NGRRadioButtons = Seq(yes,no))
}

5 changes: 5 additions & 0 deletions app/uk/gov/hmrc/ngrraldfrontend/repo/RaldRepo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ case class RaldRepo @Inject()(mongo: MongoComponent,
findAndUpdateByCredId(credId, updates: _*)
}

def insertDidYouAgreeRentWithLandlord(credId: CredId, radioValue: String): Future[Option[RaldUserAnswers]] = {
findAndUpdateByCredId(credId, Updates.set("didYouAgreeRentWithLandlord", if(radioValue == "YesTheLandlord") true else false))
}


def findByCredId(credId: CredId): Future[Option[RaldUserAnswers]] = {
collection.find(
equal("credId.value", credId.value)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
@*
* 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.ngrraldfrontend.config.AppConfig
@import uk.gov.hmrc.ngrraldfrontend.models.components.NavigationBarContent
@import uk.gov.hmrc.ngrraldfrontend.viewmodels.govuk.all._
@import uk.gov.hmrc.govukfrontend.views.html.components._
@import uk.gov.hmrc.ngrraldfrontend.views.html.components._
@import uk.gov.hmrc.ngrraldfrontend.models.forms.DidYouAgreeRentWithLandlordForm

@this(
layout: Layout,
govukRadios : GovukRadios,
govukErrorSummary: GovukErrorSummary,
saveAndContinueButton: saveAndContinueButton,
formHelper: FormWithCSRF
)

@(navigationBarContent: NavigationBarContent, selectedPropertyAddress: String, form: Form[DidYouAgreeRentWithLandlordForm], ngrRadio: Radios)(implicit request: RequestHeader, messages: Messages, appConfig: AppConfig)

@layout(pageTitle = Some(messages("didYouAgreeRentWithLandlord.title")), showBackLink = true, fullWidth = false, navigationBarContent = Some(navigationBarContent)) {

@formHelper(action = uk.gov.hmrc.ngrraldfrontend.controllers.routes.DidYouAgreeRentWithLandlordController.submit, Symbol("autoComplete") -> "off") {
@if(form.errors.nonEmpty) {
@govukErrorSummary(ErrorSummaryViewModel(form))
}
<span class="govuk-caption-m">@selectedPropertyAddress</span>
<h1 class="govuk-heading-l">@messages("didYouAgreeRentWithLandlord.title")</h1>
@govukRadios(ngrRadio)
@saveAndContinueButton(msg = messages("service.continue"), isStartButton = false)
}
}
10 changes: 6 additions & 4 deletions conf/app.routes
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ GET /have-you-agreed-rent-changes-with-landlord uk.gov.hmrc.ngrraldfront
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 /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
6 changes: 6 additions & 0 deletions conf/messages
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@ agreement.radio.breakClause.required.error = Select yes if your agreement has a
agreement.radio.conditional.breakClause.required.error = Tell us about your break clause or clauses
agreement.radio.conditional.breakClause.tooLong.error = Maximum character allowed is 250

#DidYouAgreeRentWithLandlord
didYouAgreeRentWithLandlord.title = Did you agree the rent with your landlord or their agent?
didYouAgreeRentWithLandlord.yes = Yes
didYouAgreeRentWithLandlord.no = No, a court set the rent
didYouAgreeRentWithLandlord.error.required = Select yes if you agreed the rent with your landlord or their agent

#ProvideDetailsOfFirstSecondRentPeriod
provideDetailsOfFirstSecondRentPeriod.title = Provide details of each rent period
provideDetailsOfFirstSecondRentPeriod.firstPeriod.subheading = First rent period
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* 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.mockito.ArgumentMatchers.any
import org.mockito.Mockito.when
import org.scalatest.matchers.should.Matchers.shouldBe
import play.api.test.FakeRequest
import play.api.test.Helpers.{await, contentAsString, redirectLocation, status}
import play.api.test.Helpers.{await, contentAsString, defaultAwaitTimeout, redirectLocation, status}
import play.api.http.Status.{BAD_REQUEST, OK, SEE_OTHER}
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, RaldUserAnswers}
import uk.gov.hmrc.ngrraldfrontend.models.registration.CredId
import uk.gov.hmrc.ngrraldfrontend.views.html.DidYouAgreeRentWithLandlordView

import scala.concurrent.Future

class DidYouAgreeRentWithLandlordControllerSpec extends ControllerSpecSupport {
val pageTitle = "Did you agree the rent with your landlord or their agent?"
val view: DidYouAgreeRentWithLandlordView = inject[DidYouAgreeRentWithLandlordView]
val controller: DidYouAgreeRentWithLandlordController = new DidYouAgreeRentWithLandlordController(view, mockAuthJourney, mockPropertyLinkingAction, mockRaldRepo, mcc)(mockConfig, ec)

"Did you agree rent with landlord controller" must {
"method show" must {
"Return OK and the correct view" in {
when(mockRaldRepo.findByCredId(any())) thenReturn (Future.successful(Some(RaldUserAnswers(credId = CredId(null), NewAgreement, selectedProperty = property))))
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 after submitting with written radio button" in {
when(mockRaldRepo.findByCredId(any())) thenReturn (Future.successful(Some(RaldUserAnswers(credId = CredId(null), NewAgreement, selectedProperty = property))))
mockRequest(hasCredId = true)
val result = controller.submit()(AuthenticatedUserRequest(FakeRequest(routes.DidYouAgreeRentWithLandlordController.submit)
.withFormUrlEncodedBody(("did-you-agree-rent-with-landlord-radio", "YesTheLandlord"))
.withHeaders(HeaderNames.authorisation -> "Bearer 1"), None, None, None, Some(property), credId = Some(credId.value), None, None, nino = Nino(true, Some(""))))
result.map(result => {
result.header.headers.get("Location") shouldBe Some("/ngr-rald-frontend/do-you-have-a-rent-free-period")
})
status(result) mustBe SEE_OTHER
redirectLocation(result) shouldBe Some(routes.CheckRentFreePeriodController.show.url)
}
"Return OK and the correct view after submitting with verbal radio button" in {
when(mockRaldRepo.findByCredId(any())) thenReturn (Future.successful(Some(RaldUserAnswers(credId = CredId(null), NewAgreement, selectedProperty = property))))
mockRequest(hasCredId = true)
val result = controller.submit()(AuthenticatedUserRequest(FakeRequest(routes.WhatTypeOfAgreementController.submit)
.withFormUrlEncodedBody(("did-you-agree-rent-with-landlord-radio", "NoACourtSet"))
.withHeaders(HeaderNames.authorisation -> "Bearer 1"), None, None, None, Some(property), credId = Some(credId.value), None, None, nino = Nino(true, Some(""))))
result.map(result => {
result.header.headers.get("Location") shouldBe Some("/ngr-rald-frontend/do-you-have-a-rent-free-period")
})
status(result) mustBe SEE_OTHER
redirectLocation(result) shouldBe Some(routes.CheckRentFreePeriodController.show.url)
}
"Return Form with Errors when no radio button is selected" in {
mockRequest(hasCredId = true)
val result = controller.submit()(AuthenticatedUserRequest(FakeRequest(routes.WhatTypeOfAgreementController.submit)
.withFormUrlEncodedBody(("did-you-agree-rent-with-landlord-radio", ""))
.withHeaders(HeaderNames.authorisation -> "Bearer 1"), None, None, None, Some(property), credId = Some(credId.value), None, None, nino = Nino(true, Some(""))))
result.map(result => {
result.header.headers.get("Location") shouldBe Some("/ngr-rald-frontend/what-type-of-agreement-do-you-have ")
})
status(result) mustBe BAD_REQUEST
val content = contentAsString(result)
content must include(pageTitle)
}
"Return Exception if no address is in the mongo" in {
mockRequestWithoutProperty()
val exception = intercept[NotFoundException] {
await(controller.submit()(AuthenticatedUserRequest(FakeRequest(routes.WhatTypeOfAgreementController.submit)
.withFormUrlEncodedBody(("did-you-agree-rent-with-landlord-radio", ""))
.withHeaders(HeaderNames.authorisation -> "Bearer 1"), None, None, None, Some(property), credId = Some(credId.value), None, None, nino = Nino(true, Some("")))))
}
exception.getMessage contains "Couldn't find property in mongo" mustBe true
}
}
}
}
Loading