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
Expand Up @@ -24,12 +24,11 @@ import uk.gov.hmrc.govukfrontend.views.viewmodels.table.{Table, TableRow}
import uk.gov.hmrc.http.NotFoundException
import uk.gov.hmrc.ngrraldfrontend.actions.{AuthRetrievals, DataRetrievalAction}
import uk.gov.hmrc.ngrraldfrontend.config.AppConfig
import uk.gov.hmrc.ngrraldfrontend.models.{Mode, NGRDate, ProvideDetailsOfFirstSecondRentPeriod}
import uk.gov.hmrc.ngrraldfrontend.models.{Mode, NGRDate, ProvideDetailsOfFirstSecondRentPeriod, UserAnswers}
import uk.gov.hmrc.ngrraldfrontend.models.components.NGRRadio
import uk.gov.hmrc.ngrraldfrontend.models.components.NGRRadio.buildRadios
import uk.gov.hmrc.ngrraldfrontend.models.forms.RentPeriodsForm
import uk.gov.hmrc.ngrraldfrontend.models.forms.RentPeriodsForm.form
import uk.gov.hmrc.ngrraldfrontend.models.UserAnswers
import uk.gov.hmrc.ngrraldfrontend.navigation.Navigator
import uk.gov.hmrc.ngrraldfrontend.pages.{ProvideDetailsOfFirstSecondRentPeriodPage, RentPeriodsPage}
import uk.gov.hmrc.ngrraldfrontend.repo.SessionRepository
Expand Down
19 changes: 19 additions & 0 deletions app/uk/gov/hmrc/ngrraldfrontend/models/UserAnswers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,25 @@ final case class UserAnswers(
}
}

def remove[A](page: Settable[A])(implicit writes: Writes[A]): Try[UserAnswers] = {
val updatedData = data.keys.contains(page.toString) match {
case true =>
data.removeObject(page.path) match {
case JsSuccess(jsValue, _) =>
Success(jsValue)
case JsError(errors) =>
Failure(JsResultException(errors))
}
case false => Success(data)
}

updatedData.flatMap {
d =>
val updatedAnswers = copy(data = d)
page.cleanup(None, updatedAnswers)
}
}

def getCurrentJourneyUserAnswers[A](page: Gettable[A], userAnswers: UserAnswers, credId: String)(implicit rds: Reads[A]): UserAnswers =
userAnswers.get(page) match
case Some(_) => userAnswers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ class SessionRepository @Inject()(
}

def set(answers: UserAnswers): Future[Boolean] = Mdc.preservingMdc {

val updatedAnswers = answers.copy(lastUpdated = Instant.now(clock))

collection
Expand Down
2 changes: 1 addition & 1 deletion project/AppDependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ object AppDependencies {

val compile: Seq[ModuleID] = Seq(
"uk.gov.hmrc" %% "bootstrap-frontend-play-30" % bootstrapVersion,
"uk.gov.hmrc" %% "play-frontend-hmrc-play-30" % "12.12.0",
"uk.gov.hmrc" %% "play-frontend-hmrc-play-30" % "12.14.0",
"uk.gov.hmrc.mongo" %% "hmrc-mongo-play-30" % hmrcMongoVersion,
"uk.gov.hmrc" %% "centralised-authorisation-resource-client-play-30" % "1.12.0",
"com.beachape" %% "enumeratum-play" % enumeratumVersion,
Expand Down
6 changes: 5 additions & 1 deletion test/uk/gov/hmrc/ngrraldfrontend/helpers/ViewBaseSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ import org.scalatestplus.play.PlaySpec
import org.scalatestplus.play.guice.GuiceOneAppPerSuite
import play.api.i18n.{Lang, Messages, MessagesApi, MessagesImpl}
import play.api.inject.Injector
import play.api.mvc.{AnyContentAsEmpty, RequestHeader}
import play.api.mvc.{AnyContentAsEmpty, MessagesControllerComponents, RequestHeader}
import play.api.test.{FakeRequest, Injecting}
import play.twirl.api.Html
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.ngrraldfrontend.actions.{FakeAuthenticatedRequest, FakeDataRetrievalAction}
import uk.gov.hmrc.ngrraldfrontend.mocks.MockAppConfig
import uk.gov.hmrc.ngrraldfrontend.models.UserAnswers
import uk.gov.hmrc.ngrraldfrontend.models.registration.Email
import uk.gov.hmrc.ngrraldfrontend.navigation.Navigator
import uk.gov.hmrc.ngrraldfrontend.repo.SessionRepository

trait ViewBaseSpec extends PlaySpec with GuiceOneAppPerSuite with Injecting with BeforeAndAfterEach with Matchers {
def injector: Injector = app.injector
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import org.scalatest.matchers.should.Matchers
import org.scalatest.matchers.should.Matchers.shouldBe
import play.api.mvc.Call
import uk.gov.hmrc.ngrraldfrontend.helpers.ViewBaseSpec
import uk.gov.hmrc.ngrraldfrontend.mocks.MockAppConfig
import uk.gov.hmrc.ngrraldfrontend.models.components.{NavBarContents, NavBarCurrentPage, NavBarPageContents, NavButton}

class NavigationBarComponentSpec extends ViewBaseSpec {

"NavButton" should {
"store all fields correctly" in {
val call = Call("GET", "/test")
Expand Down
68 changes: 68 additions & 0 deletions test/uk/gov/hmrc/ngrraldfrontend/models/UserAnswerSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2025 HM Revenue & Customs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package uk.gov.hmrc.ngrraldfrontend.models

import play.api.libs.json.{JsValue, Json}
import uk.gov.hmrc.ngrraldfrontend.helpers.TestSupport
import uk.gov.hmrc.ngrraldfrontend.models.AgreementType.RenewedAgreement
import uk.gov.hmrc.ngrraldfrontend.pages.{LandlordPage, TellUsAboutYourRenewedAgreementPage, WhatTypeOfLeaseRenewalPage}

import java.time.Instant

class UserAnswerSpec extends TestSupport {

val userAnswers: UserAnswers = UserAnswers(credId.value, Json.obj(
"tellUsAboutRenewedAgreement" -> "RenewedAgreement",
"whatTypeOfLeaseRenewal" -> "SurrenderAndRenewal"
), Instant.ofEpochSecond(1759232590))

val userAnswersJson: JsValue = Json.parse(
"""
|{
| "credId":"1234",
| "data":{
| "tellUsAboutRenewedAgreement": "RenewedAgreement",
| "whatTypeOfLeaseRenewal":"SurrenderAndRenewal"
| },
| "lastUpdated":{
| "$date":{
| "$numberLong":"1759232590000"
| }
| }
|}
|""".stripMargin
)

"UserAnswers" should {
"deserialize to json" in {
Json.toJson(userAnswers) mustBe userAnswersJson
}
"serialize to json" in {
userAnswersJson.as[UserAnswers] mustBe userAnswers
}
}
"remove method" should {
"Remove value without error when the key isn't there and user answers shouldn't be changed" in {
val actual = userAnswers.remove(LandlordPage).get
actual mustBe userAnswers
}
"Remove the correct value and user answers shouldn't contain it any more" in {
val actual = userAnswers.remove(WhatTypeOfLeaseRenewalPage).get
actual.get(WhatTypeOfLeaseRenewalPage) mustBe None
}
}
}
164 changes: 164 additions & 0 deletions test/uk/gov/hmrc/ngrraldfrontend/views/RentPeriodsViewSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* 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 org.scalatestplus.mockito.MockitoSugar.mock
import play.api.data.Form
import play.api.mvc.MessagesControllerComponents
import uk.gov.hmrc.ngrraldfrontend.actions.{FakeAuthenticatedRequest, FakeDataRetrievalAction}
import uk.gov.hmrc.ngrraldfrontend.controllers.RentPeriodsController
import uk.gov.hmrc.ngrraldfrontend.helpers.ViewBaseSpec
import uk.gov.hmrc.ngrraldfrontend.models.components.NGRRadio.buildRadios
import uk.gov.hmrc.ngrraldfrontend.models.forms.RentPeriodsForm
import uk.gov.hmrc.ngrraldfrontend.models.{NormalMode, ProvideDetailsOfFirstSecondRentPeriod, UserAnswers}
import uk.gov.hmrc.ngrraldfrontend.navigation.Navigator
import uk.gov.hmrc.ngrraldfrontend.repo.SessionRepository
import uk.gov.hmrc.ngrraldfrontend.views.html.RentPeriodView

import scala.concurrent.ExecutionContext

class RentPeriodsViewSpec extends ViewBaseSpec {
implicit lazy val ec: ExecutionContext = inject[ExecutionContext]
lazy val mcc: MessagesControllerComponents = inject[MessagesControllerComponents]
val fakeAuth = new FakeAuthenticatedRequest(mcc.parsers.defaultBodyParser)
val mockSessionRepository: SessionRepository = mock[SessionRepository]
val mockNavigator: Navigator = inject[Navigator]

def fakeData(answers: Option[UserAnswers]) = new FakeDataRetrievalAction(answers, None)

lazy val view: RentPeriodView = inject[RentPeriodView]
val rentPeriodsController: RentPeriodsController = new RentPeriodsController(view, fakeAuth, fakeData(None), mcc, mockSessionRepository, mockNavigator)(mockConfig, ec)
val address = "5 Brixham Marina, Berry Head Road, Brixham, Devon, TQ5 9BW"

val heading = "Rent periods"
val title = s"$heading - GOV.UK"
val firsPeriodStartDate = "1 February 2025"
val firstPeriodEndDate = "1 March 2025"
val secondPeriodStartDate = "1 April 2025"
val secondPeriodEndDate = "1 August 2025"
val firstPeriodRentQuestion = "Yes"
val firstRentAmount = "£2,300.46"
val secondRentAmount = "£1,350"
val additionPeriodQuestion = "Do you need to add another rent period?"
val yesRadio = "Yes"
val noRadio = "No"
val saveButton = "Continue"

val firstSecondRentPeriods = ProvideDetailsOfFirstSecondRentPeriod(
firstDateStart = "2025-02-01",
firstDateEnd = "2025-03-01",
firstRentPeriodRadio = true,
firstRentPeriodAmount = Some("2300.4567"),
secondDateStart = "2025-04-01",
secondDateEnd = "2025-08-01",
secondHowMuchIsRent = "1350")
val firstTable = rentPeriodsController.firstTable(firstSecondRentPeriods)
val secondTable = rentPeriodsController.secondTable(firstSecondRentPeriods)
private val form: Form[RentPeriodsForm] = RentPeriodsForm.form.fillAndValidate(RentPeriodsForm("No"))
val radio = buildRadios(form, RentPeriodsForm.ngrRadio(form))

object Selectors {
val navTitle = "head > title"
val heading = "#main-content > div > div.govuk-grid-column-two-thirds > form > h1"
val firsPeriodStartDate = "#first-period-start-date-id"
val firstPeriodEndDate = "#first-period-end-date-id"
val secondPeriodStartDate = "#second-period-start-date-id"
val secondPeriodEndDate = "#second-period-end-date-id"
val firstPeriodRentQuestion = "#first-period-has-pay-id"
val firstRentAmount = "#first-period-rent-value-id"
val secondRentAmount = "#second-period-rent-value-id"
val additionPeriodQuestion = "#main-content > div > div.govuk-grid-column-two-thirds > form > div > fieldset > legend > h1"
val yesRadio = "#main-content > div > div.govuk-grid-column-two-thirds > form > div > fieldset > div > div:nth-child(1) > label"
val noRadio = "#main-content > div > div.govuk-grid-column-two-thirds > form > div > fieldset > div > div:nth-child(2) > label"
val saveButton = "#continue"
}

"RentPeriodsView" must {
val rentPeriodsView = view(address, form, firstTable, secondTable, radio, NormalMode)
lazy implicit val document: Document = Jsoup.parse(rentPeriodsView.body)
val htmlApply = view.apply(address, form, firstTable, secondTable, radio, NormalMode).body
val htmlRender = view.render(address, form, firstTable, secondTable, radio, NormalMode, request, messages, mockConfig).body
lazy val htmlF = view.f(address, form, firstTable, secondTable, radio, NormalMode)

"htmlF is not empty" in {
htmlF.toString() must not be empty
}

"apply must nit be the same as render" in {
htmlApply mustBe htmlRender
}

"render is not empty" in {
htmlRender must not be empty
}

"show the correct title" in {
elementText(Selectors.navTitle) mustBe title
}

"show the correct heading" in {
elementText(Selectors.heading) mustBe heading
}

"show the correct first period start date" in {
elementText(Selectors.firsPeriodStartDate) mustBe firsPeriodStartDate
}

"show the correct first period end date" in {
elementText(Selectors.firstPeriodEndDate) mustBe firstPeriodEndDate
}

"show the correct second period start date" in {
elementText(Selectors.secondPeriodStartDate) mustBe secondPeriodStartDate
}

"show the correct second period end date" in {
elementText(Selectors.secondPeriodEndDate) mustBe secondPeriodEndDate
}

"show the correct answer for if pay first period rent" in {
elementText(Selectors.firstPeriodRentQuestion) mustBe firstPeriodRentQuestion
}

"show the correct first period rent amount" in {
elementText(Selectors.firstRentAmount) mustBe firstRentAmount
}

"show the correct second period rent amount" in {
elementText(Selectors.secondRentAmount) mustBe secondRentAmount
}

"show the correct radio question" in {
elementText(Selectors.additionPeriodQuestion) mustBe additionPeriodQuestion
}

"show the correct yes radio button label" in {
elementText(Selectors.yesRadio) mustBe yesRadio
}

"show the correct no radio button label" in {
elementText(Selectors.noRadio) mustBe noRadio
}

"show the correct save button" in {
elementText(Selectors.saveButton) mustBe saveButton
}
}
}