From 9ea39af4dca5de49bb29d6fdee7aee0f79d462c0 Mon Sep 17 00:00:00 2001 From: bnjn-mt Date: Thu, 16 Jul 2026 14:24:35 +0100 Subject: [PATCH 01/10] Property registration skip licensing details --- .../PropertyRegistrationJourneyFactory.kt | 3 + .../states/LicensingState.kt | 5 + .../steps/LicensingTypeStepConfig.kt | 53 ++++++--- .../steps/ProvideLicensingLaterStepConfig.kt | 34 ++++++ .../SavePropertyRegistrationDataStepConfig.kt | 4 +- .../tasks/LicensingTask.kt | 10 +- .../UpdatePropertyLicensingJourneyFactory.kt | 5 + .../shared/helpers/LicensingDetailsHelper.kt | 15 ++- .../formModels/LicensingTypeFormModel.kt | 18 ++- .../services/PropertyOwnershipService.kt | 2 + .../services/PropertyRegistrationService.kt | 10 +- src/main/resources/messages/forms.yml | 5 + .../resources/messages/registerProperty.yml | 23 ++++ .../templates/forms/licensingTypeForm.html | 15 ++- .../provideLicensingLaterOccupiedForm.html | 27 +++++ .../provideLicensingLaterUnoccupiedForm.html | 26 +++++ .../steps/LicensingTypeStepConfigTests.kt | 103 ++++++++++++++++++ .../ProvideLicensingLaterStepConfigTests.kt | 52 +++++++++ ...PropertyRegistrationDataStepConfigTests.kt | 6 +- .../helpers/LicensingDetailsHelperTests.kt | 37 +++++++ .../PropertyRegistrationServiceTests.kt | 2 + 21 files changed, 431 insertions(+), 24 deletions(-) create mode 100644 src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/ProvideLicensingLaterStepConfig.kt create mode 100644 src/main/resources/templates/forms/provideLicensingLaterOccupiedForm.html create mode 100644 src/main/resources/templates/forms/provideLicensingLaterUnoccupiedForm.html create mode 100644 src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/LicensingTypeStepConfigTests.kt create mode 100644 src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/ProvideLicensingLaterStepConfigTests.kt diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/PropertyRegistrationJourneyFactory.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/PropertyRegistrationJourneyFactory.kt index be5befa31e..86e83cb79e 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/PropertyRegistrationJourneyFactory.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/PropertyRegistrationJourneyFactory.kt @@ -88,6 +88,7 @@ import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.Prope import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.ProvideElectricalCertLaterStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.ProvideEpcLaterStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.ProvideGasCertLaterStep +import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.ProvideLicensingLaterStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.RemoveElectricalCertUploadStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.RemoveGasCertUploadStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.RentAmountStep @@ -604,6 +605,7 @@ class PropertyRegistrationJourney( override val selectiveLicenceStep: SelectiveLicenceStep, override val hmoMandatoryLicenceStep: HmoMandatoryLicenceStep, override val hmoAdditionalLicenceStep: HmoAdditionalLicenceStep, + override val provideLicensingLaterStep: ProvideLicensingLaterStep, // Occupation steps override val occupied: OccupiedStep, // Nested households and tenants task @@ -760,6 +762,7 @@ class PropertyRegistrationJourney( override var backUrlKey: Int? by delegateProvider.nullableDelegate("backUrlKey") override val allowProvideCertificateLaterRoute: Boolean = true + override val allowProvideLicensingLaterRoute: Boolean = true override fun generateJourneyId(seed: Any?): String { val user = seed as? Principal diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/states/LicensingState.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/states/LicensingState.kt index 3f0ed67350..adf5e5a6ba 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/states/LicensingState.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/states/LicensingState.kt @@ -5,13 +5,18 @@ import uk.gov.communities.prsdb.webapp.journeys.JourneyState import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.HmoAdditionalLicenceStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.HmoMandatoryLicenceStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.LicensingTypeStep +import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.ProvideLicensingLaterStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.SelectiveLicenceStep interface LicensingState : JourneyState { + val allowProvideLicensingLaterRoute: Boolean + val isOccupied: Boolean? + val licensingTypeStep: LicensingTypeStep val selectiveLicenceStep: SelectiveLicenceStep val hmoMandatoryLicenceStep: HmoMandatoryLicenceStep val hmoAdditionalLicenceStep: HmoAdditionalLicenceStep + val provideLicensingLaterStep: ProvideLicensingLaterStep fun getLicenceNumberOrNull(): String? = when (licensingTypeStep.formModelOrNull?.licensingType) { diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/LicensingTypeStepConfig.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/LicensingTypeStepConfig.kt index 827906b0a0..f56ddd9123 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/LicensingTypeStepConfig.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/LicensingTypeStepConfig.kt @@ -2,10 +2,14 @@ package uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps import uk.gov.communities.prsdb.webapp.annotations.webAnnotations.JourneyFrameworkComponent import uk.gov.communities.prsdb.webapp.config.managers.FeatureFlagManager +import uk.gov.communities.prsdb.webapp.constants.CONTINUE_BUTTON_ACTION_NAME +import uk.gov.communities.prsdb.webapp.constants.PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING +import uk.gov.communities.prsdb.webapp.constants.PROVIDE_THIS_LATER_BUTTON_ACTION_NAME import uk.gov.communities.prsdb.webapp.constants.enums.LicensingType import uk.gov.communities.prsdb.webapp.journeys.AbstractRequestableStepConfig -import uk.gov.communities.prsdb.webapp.journeys.JourneyState import uk.gov.communities.prsdb.webapp.journeys.JourneyStep.RequestableStep +import uk.gov.communities.prsdb.webapp.journeys.UnrecoverableJourneyStateException +import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.states.LicensingState import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.LicensingTypeFormModel import uk.gov.communities.prsdb.webapp.models.viewModels.formModels.RadiosButtonViewModel import uk.gov.communities.prsdb.webapp.models.viewModels.formModels.RadiosDividerViewModel @@ -13,14 +17,21 @@ import uk.gov.communities.prsdb.webapp.models.viewModels.formModels.RadiosDivide @JourneyFrameworkComponent class LicensingTypeStepConfig( private val featureFlagManager: FeatureFlagManager, -) : AbstractRequestableStepConfig() { +) : AbstractRequestableStepConfig() { override val formModelClass = LicensingTypeFormModel::class - override fun getStepSpecificContent(state: JourneyState): Map { - // TODO(PDJB-990): add a 'Provide this later' button to the licensing page behind the FF: pdjb-939-property-registration-restructure-and-skipping/PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING + override fun getStepSpecificContent(state: LicensingState): Map { + val showProvideThisLater = + state.allowProvideLicensingLaterRoute && + featureFlagManager.checkFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) return mapOf( "fieldSetHeading" to "forms.licensingType.fieldSetHeading", "fieldSetHint" to "forms.licensingType.fieldSetHint", + "submitButtonText" to "forms.buttons.saveAndContinue", + "showSecondarySubmitButton" to showProvideThisLater, + "submitButtonAction" to CONTINUE_BUTTON_ACTION_NAME, + "secondarySubmitButtonText" to "forms.buttons.provideThisLater", + "secondarySubmitButtonAction" to PROVIDE_THIS_LATER_BUTTON_ACTION_NAME, "radioOptions" to listOf( RadiosButtonViewModel( @@ -47,15 +58,30 @@ class LicensingTypeStepConfig( ) } - override fun chooseTemplate(state: JourneyState): String = "forms/licensingTypeForm" + override fun chooseTemplate(state: LicensingState): String = "forms/licensingTypeForm" - override fun mode(state: JourneyState) = - getFormModelFromStateOrNull(state)?.licensingType?.let { licensingType -> - when (licensingType) { - LicensingType.SELECTIVE_LICENCE -> LicensingTypeMode.SELECTIVE_LICENCE - LicensingType.HMO_MANDATORY_LICENCE -> LicensingTypeMode.HMO_MANDATORY_LICENCE - LicensingType.HMO_ADDITIONAL_LICENCE -> LicensingTypeMode.HMO_ADDITIONAL_LICENCE - LicensingType.NO_LICENSING -> LicensingTypeMode.NO_LICENSING + override fun mode(state: LicensingState) = + getFormModelFromStateOrNull(state)?.let { formModel -> + if (formModel.action == PROVIDE_THIS_LATER_BUTTON_ACTION_NAME) { + if (state.allowProvideLicensingLaterRoute && + featureFlagManager.checkFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + ) { + LicensingTypeMode.PROVIDE_LATER + } else { + throw UnrecoverableJourneyStateException( + state.journeyId, + "The 'Provide this later' route is not available for this journey", + ) + } + } else { + formModel.licensingType?.let { licensingType -> + when (licensingType) { + LicensingType.SELECTIVE_LICENCE -> LicensingTypeMode.SELECTIVE_LICENCE + LicensingType.HMO_MANDATORY_LICENCE -> LicensingTypeMode.HMO_MANDATORY_LICENCE + LicensingType.HMO_ADDITIONAL_LICENCE -> LicensingTypeMode.HMO_ADDITIONAL_LICENCE + LicensingType.NO_LICENSING -> LicensingTypeMode.NO_LICENSING + } + } } } } @@ -63,7 +89,7 @@ class LicensingTypeStepConfig( @JourneyFrameworkComponent final class LicensingTypeStep( stepConfig: LicensingTypeStepConfig, -) : RequestableStep(stepConfig) { +) : RequestableStep(stepConfig) { companion object { const val ROUTE_SEGMENT = "licensing-type" } @@ -74,4 +100,5 @@ enum class LicensingTypeMode { HMO_MANDATORY_LICENCE, HMO_ADDITIONAL_LICENCE, NO_LICENSING, + PROVIDE_LATER, } diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/ProvideLicensingLaterStepConfig.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/ProvideLicensingLaterStepConfig.kt new file mode 100644 index 0000000000..5eca652240 --- /dev/null +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/ProvideLicensingLaterStepConfig.kt @@ -0,0 +1,34 @@ +package uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps + +import uk.gov.communities.prsdb.webapp.annotations.webAnnotations.JourneyFrameworkComponent +import uk.gov.communities.prsdb.webapp.journeys.AbstractRequestableStepConfig +import uk.gov.communities.prsdb.webapp.journeys.JourneyStep.RequestableStep +import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.states.LicensingState +import uk.gov.communities.prsdb.webapp.journeys.shared.Complete +import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.NoInputFormModel + +@JourneyFrameworkComponent +class ProvideLicensingLaterStepConfig : AbstractRequestableStepConfig() { + override val formModelClass = NoInputFormModel::class + + override fun getStepSpecificContent(state: LicensingState) = + mapOf( + "submitButtonText" to if (state.isOccupied == true) "forms.buttons.continue" else "forms.buttons.saveAndContinue", + ) + + override fun chooseTemplate(state: LicensingState): String = + state.isOccupied?.let { isOccupied -> + if (isOccupied) "forms/provideLicensingLaterOccupiedForm" else "forms/provideLicensingLaterUnoccupiedForm" + } ?: throw IllegalStateException("ProvideLicensingLaterStep should not be reachable before isOccupied is set") + + override fun mode(state: LicensingState) = getFormModelFromStateOrNull(state)?.let { Complete.COMPLETE } +} + +@JourneyFrameworkComponent +final class ProvideLicensingLaterStep( + stepConfig: ProvideLicensingLaterStepConfig, +) : RequestableStep(stepConfig) { + companion object { + const val ROUTE_SEGMENT = "provide-licensing-later" + } +} diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfig.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfig.kt index 6c67901be1..3078fa04a3 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfig.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfig.kt @@ -14,7 +14,6 @@ import uk.gov.communities.prsdb.webapp.journeys.JourneyStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.PropertyRegistrationJourneyState import uk.gov.communities.prsdb.webapp.journeys.shared.Complete import uk.gov.communities.prsdb.webapp.journeys.shared.YesOrNo -import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.LicensingTypeFormModel import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.NewNumberOfPeopleFormModel import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.NumberOfBedroomsFormModel import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.NumberOfHouseholdsFormModel @@ -68,7 +67,7 @@ class SavePropertyRegistrationDataStepConfig( } else { null }, - licenseType = state.licensingTypeStep.formModel.notNullValue(LicensingTypeFormModel::licensingType), + licenseType = state.licensingTypeStep.formModelOrNull?.licensingType, licenceNumber = state.getLicenceNumberOrNull() ?: "", ownershipType = state.ownershipTypeStep.formModel.notNullValue(OwnershipTypeFormModel::ownershipType), isOccupied = isOccupied, @@ -138,6 +137,7 @@ class SavePropertyRegistrationDataStepConfig( .formModelIfReachableOrNull ?.exemptionReason, epcProvideLater = state.hasEpcStep.outcome == HasEpcMode.PROVIDE_LATER, + licenseProvideLater = state.licensingTypeStep.outcome == LicensingTypeMode.PROVIDE_LATER, ) } } diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/tasks/LicensingTask.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/tasks/LicensingTask.kt index 447914e7d0..8170c4e86f 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/tasks/LicensingTask.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/tasks/LicensingTask.kt @@ -11,6 +11,7 @@ import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.HmoAd import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.HmoMandatoryLicenceStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.LicensingTypeMode import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.LicensingTypeStep +import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.ProvideLicensingLaterStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.SelectiveLicenceStep @JourneyFrameworkComponent @@ -19,7 +20,6 @@ class LicensingTask( ) : Task() { override fun makeSubJourney(state: LicensingState) = subJourney(state) { - // TODO(PDJB-990): route to the 'provide details about licensing later' page when 'Provide this later' is selected behind the FF: pdjb-939-property-registration-restructure-and-skipping/PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING step(journey.licensingTypeStep) { routeSegment(LicensingTypeStep.ROUTE_SEGMENT) nextStep { mode -> @@ -28,6 +28,7 @@ class LicensingTask( LicensingTypeMode.HMO_MANDATORY_LICENCE -> journey.hmoMandatoryLicenceStep LicensingTypeMode.HMO_ADDITIONAL_LICENCE -> journey.hmoAdditionalLicenceStep LicensingTypeMode.NO_LICENSING -> exitStep + LicensingTypeMode.PROVIDE_LATER -> journey.provideLicensingLaterStep } } } @@ -46,6 +47,12 @@ class LicensingTask( parents { journey.licensingTypeStep.hasOutcome(LicensingTypeMode.HMO_ADDITIONAL_LICENCE) } nextStep { exitStep } } + step(journey.provideLicensingLaterStep) { + routeSegment(ProvideLicensingLaterStep.ROUTE_SEGMENT) + parents { journey.licensingTypeStep.hasOutcome(LicensingTypeMode.PROVIDE_LATER) } + nextStep { exitStep } + savable() + } exitStep { parents { OrParents( @@ -53,6 +60,7 @@ class LicensingTask( journey.selectiveLicenceStep.isComplete(), journey.hmoMandatoryLicenceStep.isComplete(), journey.hmoAdditionalLicenceStep.isComplete(), + journey.provideLicensingLaterStep.isComplete(), ) } } diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/update/updateLicensing/UpdatePropertyLicensingJourneyFactory.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/update/updateLicensing/UpdatePropertyLicensingJourneyFactory.kt index e32c3819aa..0385b32d59 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/update/updateLicensing/UpdatePropertyLicensingJourneyFactory.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/update/updateLicensing/UpdatePropertyLicensingJourneyFactory.kt @@ -17,6 +17,7 @@ import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.Finis import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.HmoAdditionalLicenceStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.HmoMandatoryLicenceStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.LicensingTypeStep +import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.ProvideLicensingLaterStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.SelectiveLicenceStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.tasks.LicensingTask import uk.gov.communities.prsdb.webapp.journeys.shared.states.CheckYourAnswersJourneyState @@ -110,6 +111,7 @@ class UpdateLicensingJourney( override val selectiveLicenceStep: SelectiveLicenceStep, override val hmoMandatoryLicenceStep: HmoMandatoryLicenceStep, override val hmoAdditionalLicenceStep: HmoAdditionalLicenceStep, + override val provideLicensingLaterStep: ProvideLicensingLaterStep, // Check your answers step override val cyaStep: UpdateLicensingCyaStep, override val finishCyaStep: FinishCyaJourneyStep, @@ -126,6 +128,9 @@ class UpdateLicensingJourney( override var originalJourneyUpdated: Instant? by delegateProvider.nullableDelegate("originalJourneyUpdated") override var cyaUrlPath: String? by delegateProvider.nullableDelegate("cyaRouteSegment") + + override val allowProvideLicensingLaterRoute: Boolean = false + override val isOccupied: Boolean? = null } interface UpdateLicensingJourneyState : diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/shared/helpers/LicensingDetailsHelper.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/shared/helpers/LicensingDetailsHelper.kt index d0acf2de54..950812f438 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/shared/helpers/LicensingDetailsHelper.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/shared/helpers/LicensingDetailsHelper.kt @@ -2,10 +2,12 @@ package uk.gov.communities.prsdb.webapp.journeys.shared.helpers import uk.gov.communities.prsdb.webapp.annotations.webAnnotations.PrsdbWebService import uk.gov.communities.prsdb.webapp.config.managers.FeatureFlagManager +import uk.gov.communities.prsdb.webapp.constants.PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING import uk.gov.communities.prsdb.webapp.constants.enums.LicensingType import uk.gov.communities.prsdb.webapp.exceptions.NotNullFormModelValueIsNullException.Companion.notNullValue import uk.gov.communities.prsdb.webapp.journeys.Destination import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.states.LicensingState +import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.LicensingTypeMode import uk.gov.communities.prsdb.webapp.journeys.shared.states.CheckYourAnswersJourneyState import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.LicensingTypeFormModel import uk.gov.communities.prsdb.webapp.models.viewModels.summaryModels.SummaryListRowViewModel @@ -17,7 +19,18 @@ class LicensingDetailsHelper( fun getCheckYourAnswersSummaryList( state: T, ): List where T : LicensingState, T : CheckYourAnswersJourneyState { - // TODO(PDJB-990): show 'Provide this later' in the licensing CYA row (property registration only) behind the FF: pdjb-939-property-registration-restructure-and-skipping/PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING + if (featureFlagManager.checkFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) && + state.licensingTypeStep.outcome == LicensingTypeMode.PROVIDE_LATER + ) { + return listOf( + SummaryListRowViewModel.forCheckYourAnswersPage( + "forms.checkPropertyAnswers.propertyDetails.licensingType", + "forms.checkPropertyAnswers.propertyDetails.licensingProvideLater", + Destination.VisitableStep(state.licensingTypeStep, state.getCyaJourneyId(state.licensingTypeStep)), + ), + ) + } + return state.licensingTypeStep.formModel.notNullValue(LicensingTypeFormModel::licensingType).let { licensingType -> listOfNotNull( SummaryListRowViewModel.forCheckYourAnswersPage( diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/models/requestModels/formModels/LicensingTypeFormModel.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/models/requestModels/formModels/LicensingTypeFormModel.kt index 9c45aedc6e..9912fb98b0 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/models/requestModels/formModels/LicensingTypeFormModel.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/models/requestModels/formModels/LicensingTypeFormModel.kt @@ -1,15 +1,29 @@ package uk.gov.communities.prsdb.webapp.models.requestModels.formModels -import jakarta.validation.constraints.NotNull import uk.gov.communities.prsdb.webapp.constants.enums.LicensingType import uk.gov.communities.prsdb.webapp.database.entity.PropertyOwnership +import uk.gov.communities.prsdb.webapp.validation.ConstraintDescriptor +import uk.gov.communities.prsdb.webapp.validation.DelegatedPropertyConstraintValidator import uk.gov.communities.prsdb.webapp.validation.IsValidPrioritised +import uk.gov.communities.prsdb.webapp.validation.ValidatedBy @IsValidPrioritised class LicensingTypeFormModel : FormModel { - @NotNull(message = "forms.licensingType.radios.error.missing") + @ValidatedBy( + constraints = [ + ConstraintDescriptor( + messageKey = "forms.licensingType.radios.error.missing", + validatorType = DelegatedPropertyConstraintValidator::class, + targetMethod = "licensingTypeIsValidForAction", + ), + ], + ) var licensingType: LicensingType? = null + var action: String? = null + + fun licensingTypeIsValidForAction(): Boolean = action == "provideThisLater" || licensingType != null + companion object { fun fromPropertyOwnership(propertyOwnership: PropertyOwnership): LicensingTypeFormModel = LicensingTypeFormModel().apply { diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyOwnershipService.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyOwnershipService.kt index 751ed95a3c..e45b48aa0f 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyOwnershipService.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyOwnershipService.kt @@ -61,6 +61,7 @@ class PropertyOwnershipService( rentAmount: BigDecimal?, customPropertyType: String?, markedJointLandlord: Boolean = false, + licenseProvideLater: Boolean? = null, ): PropertyOwnership { val registrationNumber = registrationNumberService.createRegistrationNumber(RegistrationNumberType.PROPERTY) @@ -85,6 +86,7 @@ class PropertyOwnershipService( customRentFrequency = customRentFrequency, rentAmount = rentAmount, markedJointLandlord = markedJointLandlord, + licenseProvideLater = licenseProvideLater, ).apply { if (isOccupied) lastOccupiedDate = LocalDate.now() }, diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationService.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationService.kt index 4b104cc4a9..fc302d89a3 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationService.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationService.kt @@ -40,7 +40,7 @@ class PropertyRegistrationService( fun registerProperty( addressModel: AddressDataModel, propertyType: PropertyType, - licenseType: LicensingType, + licenseType: LicensingType?, licenceNumber: String, ownershipType: OwnershipType, isOccupied: Boolean, @@ -72,6 +72,7 @@ class PropertyRegistrationService( epcExemptionReason: EpcExemptionReason? = null, epcMeesExemptionReason: MeesExemptionReason? = null, epcProvideLater: Boolean? = null, + licenseProvideLater: Boolean = false, ) { val landlord = individualLandlordRepository.findByBaseUser_Id(baseUserId) @@ -98,6 +99,7 @@ class PropertyRegistrationService( customPropertyType, markedJointLandlord, mutableSetOf(landlord), + licenseProvideLater = licenseProvideLater, ) propertyComplianceService.saveRegistrationComplianceData( @@ -127,7 +129,7 @@ class PropertyRegistrationService( private fun createPropertyOwnershipAndRelatedEntities( addressModel: AddressDataModel, propertyType: PropertyType, - licenseType: LicensingType, + licenseType: LicensingType?, licenceNumber: String, ownershipType: OwnershipType, isOccupied: Boolean, @@ -143,6 +145,7 @@ class PropertyRegistrationService( customPropertyType: String?, markedJointLandlord: Boolean, landlords: MutableSet, + licenseProvideLater: Boolean = false, ): PropertyOwnership { if (addressModel.uprn != null && propertyOwnershipRepository.existsByIsActiveTrueAndAddress_Uprn(addressModel.uprn)) { throw EntityExistsException("Address already registered") @@ -151,7 +154,7 @@ class PropertyRegistrationService( val address = addressService.findOrCreateAddress(addressModel) val license = - if (licenseType != LicensingType.NO_LICENSING) { + if (licenseType != null) { licenseService.createLicense(licenseType, licenceNumber) } else { null @@ -175,6 +178,7 @@ class PropertyRegistrationService( markedJointLandlord = markedJointLandlord, address = address, license = license, + licenseProvideLater = licenseProvideLater, ) } diff --git a/src/main/resources/messages/forms.yml b/src/main/resources/messages/forms.yml index 0ff427ea15..307d673b39 100644 --- a/src/main/resources/messages/forms.yml +++ b/src/main/resources/messages/forms.yml @@ -645,6 +645,11 @@ checkPropertyAnswers: ownership: Ownership type licensingType: Licensing type noLicensing: None + licensingProvideLater: Provide this later + additionalLandlords: + heading: Additional landlords + interestedParties: + heading: Interested parties tenancyDetails: heading: Tenancy and rental information occupied: Occupied by tenants diff --git a/src/main/resources/messages/registerProperty.yml b/src/main/resources/messages/registerProperty.yml index a24b27a769..fce24d37b3 100644 --- a/src/main/resources/messages/registerProperty.yml +++ b/src/main/resources/messages/registerProperty.yml @@ -121,3 +121,26 @@ confirmMissingCompliance: error: missing: Select whether you want to submit this registration button: Confirm and submit +provideLicensingLater: + occupied: + heading: Provide details about property licensing later + paragraph: + one: You can continue and submit your registration now, but you'll need to return later and provide details about this property's license. + whenToAdd: + heading: When you must do this by + insetText: To keep your property registered, you must provide its licensing details within 28 days. + paragraph: This is because you've told us this property's occupied by tenants. + unoccupied: + heading: Provide details about property licensing later + paragraph: + one: If you're unsure, check with the local council if your property needs a license to be rented out. + whenToAdd: + heading: When you'll need to provide these property licensing details + paragraph: + one: You can continue to finish your registration and get a Property Registration Number. + two: "Once your property's occupied, you have 28 days to return and tell us:" + weWillNeedToKnow: + intro: "We'll need to know:" + bullet: + one: if your property needs a licence or not + two: details about the licence (if your property needs one) diff --git a/src/main/resources/templates/forms/licensingTypeForm.html b/src/main/resources/templates/forms/licensingTypeForm.html index 6a83a728a8..4af3e4ecde 100644 --- a/src/main/resources/templates/forms/licensingTypeForm.html +++ b/src/main/resources/templates/forms/licensingTypeForm.html @@ -4,6 +4,11 @@ + + + + + @@ -11,6 +16,14 @@ th:replace="~{fragments/forms/fieldSet :: fieldSet(~{::#fieldset-content/content()}, 'licensingType', #{${fieldSetHeading}}, #{${fieldSetHint}})}"> - + +
+ + +
+
+ + +
diff --git a/src/main/resources/templates/forms/provideLicensingLaterOccupiedForm.html b/src/main/resources/templates/forms/provideLicensingLaterOccupiedForm.html new file mode 100644 index 0000000000..38b1a3234f --- /dev/null +++ b/src/main/resources/templates/forms/provideLicensingLaterOccupiedForm.html @@ -0,0 +1,27 @@ + + + + + + + + +
+

registerProperty.provideLicensingLater.occupied.heading

+
+
+

registerProperty.provideLicensingLater.occupied.paragraph.one

+

registerProperty.provideLicensingLater.occupied.whenToAdd.heading

+
registerProperty.provideLicensingLater.occupied.whenToAdd.insetText
+

registerProperty.provideLicensingLater.occupied.whenToAdd.paragraph

+

registerProperty.provideLicensingLater.weWillNeedToKnow.intro

+
    +
  • registerProperty.provideLicensingLater.weWillNeedToKnow.bullet.one
  • +
  • registerProperty.provideLicensingLater.weWillNeedToKnow.bullet.two
  • +
+
+
+ + + + diff --git a/src/main/resources/templates/forms/provideLicensingLaterUnoccupiedForm.html b/src/main/resources/templates/forms/provideLicensingLaterUnoccupiedForm.html new file mode 100644 index 0000000000..e66ef059d4 --- /dev/null +++ b/src/main/resources/templates/forms/provideLicensingLaterUnoccupiedForm.html @@ -0,0 +1,26 @@ + + + + + + + + +
+

registerProperty.provideLicensingLater.unoccupied.heading

+
+
+

registerProperty.provideLicensingLater.unoccupied.paragraph.one

+

registerProperty.provideLicensingLater.unoccupied.whenToAdd.heading

+

registerProperty.provideLicensingLater.unoccupied.whenToAdd.paragraph.one

+

registerProperty.provideLicensingLater.unoccupied.whenToAdd.paragraph.two

+
    +
  • registerProperty.provideLicensingLater.weWillNeedToKnow.bullet.one
  • +
  • registerProperty.provideLicensingLater.weWillNeedToKnow.bullet.two
  • +
+
+
+ + + + diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/LicensingTypeStepConfigTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/LicensingTypeStepConfigTests.kt new file mode 100644 index 0000000000..53c098209b --- /dev/null +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/LicensingTypeStepConfigTests.kt @@ -0,0 +1,103 @@ +package uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.whenever +import uk.gov.communities.prsdb.webapp.config.managers.FeatureFlagManager +import uk.gov.communities.prsdb.webapp.constants.CONTINUE_BUTTON_ACTION_NAME +import uk.gov.communities.prsdb.webapp.constants.PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING +import uk.gov.communities.prsdb.webapp.constants.PROVIDE_THIS_LATER_BUTTON_ACTION_NAME +import uk.gov.communities.prsdb.webapp.journeys.UnrecoverableJourneyStateException +import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.states.LicensingState +import uk.gov.communities.prsdb.webapp.testHelpers.mockObjects.AlwaysTrueValidator + +@ExtendWith(MockitoExtension::class) +class LicensingTypeStepConfigTests { + @Mock + lateinit var mockState: LicensingState + + @Mock + lateinit var featureFlagManager: FeatureFlagManager + + val routeSegment = LicensingTypeStep.ROUTE_SEGMENT + + @Test + fun `mode returns null when form model is not present`() { + val stepConfig = setupStepConfig() + whenever(mockState.getStepData(routeSegment)).thenReturn(null) + + val result = stepConfig.mode(mockState) + + assertNull(result) + } + + @Test + fun `mode returns null when licensingType is null and action is not provideThisLater`() { + val stepConfig = setupStepConfig() + whenever(mockState.getStepData(routeSegment)) + .thenReturn(mapOf("licensingType" to null, "action" to CONTINUE_BUTTON_ACTION_NAME)) + + val result = stepConfig.mode(mockState) + + assertNull(result) + } + + @Test + fun `mode returns SELECTIVE_LICENCE when licensingType is SELECTIVE_LICENCE`() { + val stepConfig = setupStepConfig() + whenever(mockState.getStepData(routeSegment)) + .thenReturn(mapOf("licensingType" to "SELECTIVE_LICENCE", "action" to CONTINUE_BUTTON_ACTION_NAME)) + + val result = stepConfig.mode(mockState) + + assertEquals(LicensingTypeMode.SELECTIVE_LICENCE, result) + } + + @Test + fun `mode returns PROVIDE_LATER when action is provideThisLater and route is allowed and FF is on`() { + val stepConfig = setupStepConfig() + whenever(mockState.allowProvideLicensingLaterRoute).thenReturn(true) + whenever(featureFlagManager.checkFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING)).thenReturn(true) + whenever(mockState.getStepData(routeSegment)) + .thenReturn(mapOf("licensingType" to null, "action" to PROVIDE_THIS_LATER_BUTTON_ACTION_NAME)) + + val result = stepConfig.mode(mockState) + + assertEquals(LicensingTypeMode.PROVIDE_LATER, result) + } + + @Test + fun `mode throws UnrecoverableJourneyStateException when action is provideThisLater but allowProvideLicensingLaterRoute is false`() { + val stepConfig = setupStepConfig() + whenever(mockState.allowProvideLicensingLaterRoute).thenReturn(false) + whenever(mockState.journeyId).thenReturn("test-journey-id") + whenever(mockState.getStepData(routeSegment)) + .thenReturn(mapOf("licensingType" to null, "action" to PROVIDE_THIS_LATER_BUTTON_ACTION_NAME)) + + assertThrows { stepConfig.mode(mockState) } + } + + @Test + fun `mode throws UnrecoverableJourneyStateException when action is provideThisLater but FF is off`() { + val stepConfig = setupStepConfig() + whenever(mockState.allowProvideLicensingLaterRoute).thenReturn(true) + whenever(featureFlagManager.checkFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING)).thenReturn(false) + whenever(mockState.journeyId).thenReturn("test-journey-id") + whenever(mockState.getStepData(routeSegment)) + .thenReturn(mapOf("licensingType" to null, "action" to PROVIDE_THIS_LATER_BUTTON_ACTION_NAME)) + + assertThrows { stepConfig.mode(mockState) } + } + + private fun setupStepConfig(): LicensingTypeStepConfig { + val stepConfig = LicensingTypeStepConfig(featureFlagManager) + stepConfig.routeSegment = routeSegment + stepConfig.validator = AlwaysTrueValidator() + return stepConfig + } +} diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/ProvideLicensingLaterStepConfigTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/ProvideLicensingLaterStepConfigTests.kt new file mode 100644 index 0000000000..f7b4d4cc41 --- /dev/null +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/ProvideLicensingLaterStepConfigTests.kt @@ -0,0 +1,52 @@ +package uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.whenever +import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.states.LicensingState +import uk.gov.communities.prsdb.webapp.testHelpers.mockObjects.AlwaysTrueValidator + +@ExtendWith(MockitoExtension::class) +class ProvideLicensingLaterStepConfigTests { + @Mock + lateinit var mockState: LicensingState + + @Test + fun `chooseTemplate returns occupied template when isOccupied is true`() { + val stepConfig = setupStepConfig() + whenever(mockState.isOccupied).thenReturn(true) + + val result = stepConfig.chooseTemplate(mockState) + + assertEquals("forms/provideLicensingLaterOccupiedForm", result) + } + + @Test + fun `chooseTemplate returns unoccupied template when isOccupied is false`() { + val stepConfig = setupStepConfig() + whenever(mockState.isOccupied).thenReturn(false) + + val result = stepConfig.chooseTemplate(mockState) + + assertEquals("forms/provideLicensingLaterUnoccupiedForm", result) + } + + @Test + fun `chooseTemplate throws IllegalStateException when isOccupied is null`() { + val stepConfig = setupStepConfig() + whenever(mockState.isOccupied).thenReturn(null) + + assertThrows { stepConfig.chooseTemplate(mockState) } + } + + private fun setupStepConfig(): ProvideLicensingLaterStepConfig { + val stepConfig = ProvideLicensingLaterStepConfig() + stepConfig.routeSegment = ProvideLicensingLaterStep.ROUTE_SEGMENT + stepConfig.validator = AlwaysTrueValidator() + return stepConfig + } +} diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfigTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfigTests.kt index ce24b59fb3..739c22c444 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfigTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfigTests.kt @@ -159,6 +159,7 @@ class SavePropertyRegistrationDataStepConfigTests { epcExemptionReason = eq(epcExemptionReason), epcMeesExemptionReason = eq(meesExemptionReason), epcProvideLater = eq(false), + licenseProvideLater = eq(false), ) } @@ -206,6 +207,7 @@ class SavePropertyRegistrationDataStepConfigTests { epcExemptionReason = anyOrNull(), epcMeesExemptionReason = anyOrNull(), epcProvideLater = anyOrNull(), + licenseProvideLater = anyOrNull(), ), ).thenThrow(EntityExistsException("Address already registered")) @@ -263,6 +265,7 @@ class SavePropertyRegistrationDataStepConfigTests { epcExemptionReason = isNull(), epcMeesExemptionReason = isNull(), epcProvideLater = anyOrNull(), + licenseProvideLater = anyOrNull(), ) } @@ -319,7 +322,8 @@ class SavePropertyRegistrationDataStepConfigTests { val mockLicensingTypeStep = mock() val licensingTypeFormModel = LicensingTypeFormModel().apply { licensingType = LicensingType.SELECTIVE_LICENCE } whenever(mockState.licensingTypeStep).thenReturn(mockLicensingTypeStep) - whenever(mockLicensingTypeStep.formModel).thenReturn(licensingTypeFormModel) + whenever(mockLicensingTypeStep.formModelOrNull).thenReturn(licensingTypeFormModel) + whenever(mockLicensingTypeStep.outcome).thenReturn(LicensingTypeMode.SELECTIVE_LICENCE) whenever(mockState.getLicenceNumberOrNull()).thenReturn(null) diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/shared/helpers/LicensingDetailsHelperTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/shared/helpers/LicensingDetailsHelperTests.kt index 945feb7003..a905b30a7b 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/shared/helpers/LicensingDetailsHelperTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/shared/helpers/LicensingDetailsHelperTests.kt @@ -5,11 +5,13 @@ import org.mockito.Mockito.mock import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.whenever import uk.gov.communities.prsdb.webapp.config.managers.FeatureFlagManager +import uk.gov.communities.prsdb.webapp.constants.PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING import uk.gov.communities.prsdb.webapp.constants.enums.LicensingType import uk.gov.communities.prsdb.webapp.journeys.JourneyState import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.states.LicensingState import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.HmoAdditionalLicenceStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.HmoMandatoryLicenceStep +import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.LicensingTypeMode import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.LicensingTypeStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.SelectiveLicenceStep import uk.gov.communities.prsdb.webapp.journeys.shared.states.CheckYourAnswersJourneyState @@ -74,6 +76,26 @@ class LicensingDetailsHelperTests { } } + @Test + fun `When licensing was skipped and FF is on, getCheckYourAnswersSummaryList returns a single provide-this-later row`() { + // Arrange + whenever(featureFlagManager.checkFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING)).thenReturn(true) + val state = createMockLicensingStateWithSkip() + + // Act + val summaryList = licensingDetailsHelper.getCheckYourAnswersSummaryList(state) + + // Assert + summaryList.single().let { row -> + assertEquals("forms.checkPropertyAnswers.propertyDetails.licensingType", row.fieldHeading) + assertEquals("forms.checkPropertyAnswers.propertyDetails.licensingProvideLater", row.fieldValue) + assertEquals( + listOf(SummaryListRowActionsViewModel("forms.links.change", "licensing-type?journeyId=$childJourneyId")), + row.actions, + ) + } + } + interface TestableLicensingState : CheckYourAnswersJourneyState, LicensingState, @@ -129,4 +151,19 @@ class LicensingDetailsHelperTests { return stateMock } + + fun createMockLicensingStateWithSkip(): TestableLicensingState { + val stateMock = mock() + + val typeStepMock = + mock().apply { + whenever(this.outcome).thenReturn(LicensingTypeMode.PROVIDE_LATER) + whenever(this.routeSegment).thenReturn("licensing-type") + whenever(this.isStepReachable).thenReturn(true) + } + whenever(stateMock.licensingTypeStep).thenReturn(typeStepMock) + whenever(stateMock.getCyaJourneyId(anyOrNull())).thenReturn(childJourneyId) + + return stateMock + } } diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationServiceTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationServiceTests.kt index 2111577062..55dc3a0fc1 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationServiceTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationServiceTests.kt @@ -807,6 +807,7 @@ class PropertyRegistrationServiceTests { rentAmount = anyOrNull(), customPropertyType = anyOrNull(), markedJointLandlord = any(), + licenseProvideLater = any(), ), ).thenReturn(expectedPropertyOwnership) whenever(mockAbsoluteUrlProvider.buildLandlordDashboardUri()).thenReturn(URI("https:gov.uk")) @@ -853,6 +854,7 @@ class PropertyRegistrationServiceTests { rentAmount = anyOrNull(), customPropertyType = anyOrNull(), markedJointLandlord = eq(true), + licenseProvideLater = any(), ) } } From fb5aef4c95a83ec45cf2669cdbf81a7579a95e5c Mon Sep 17 00:00:00 2001 From: bnjn-mt Date: Thu, 16 Jul 2026 14:50:30 +0100 Subject: [PATCH 02/10] =?UTF-8?q?Added=20=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/messages/registerProperty.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/resources/messages/registerProperty.yml b/src/main/resources/messages/registerProperty.yml index fce24d37b3..3116b99b16 100644 --- a/src/main/resources/messages/registerProperty.yml +++ b/src/main/resources/messages/registerProperty.yml @@ -125,22 +125,22 @@ provideLicensingLater: occupied: heading: Provide details about property licensing later paragraph: - one: You can continue and submit your registration now, but you'll need to return later and provide details about this property's license. + one: You can continue and submit your registration now, but you’ll need to return later and provide details about this property’s license. whenToAdd: heading: When you must do this by insetText: To keep your property registered, you must provide its licensing details within 28 days. - paragraph: This is because you've told us this property's occupied by tenants. + paragraph: This is because you’ve told us this property’s occupied by tenants. unoccupied: heading: Provide details about property licensing later paragraph: - one: If you're unsure, check with the local council if your property needs a license to be rented out. + one: If you’re unsure, check with the local council if your property needs a license to be rented out. whenToAdd: - heading: When you'll need to provide these property licensing details + heading: When you’ll need to provide these property licensing details paragraph: one: You can continue to finish your registration and get a Property Registration Number. - two: "Once your property's occupied, you have 28 days to return and tell us:" + two: 'Once your property’s occupied, you have 28 days to return and tell us:' weWillNeedToKnow: - intro: "We'll need to know:" + intro: 'We’ll need to know:' bullet: one: if your property needs a licence or not two: details about the licence (if your property needs one) From ac4f8415189d940ae585ff484674e7de4fef20a5 Mon Sep 17 00:00:00 2001 From: bnjn-mt Date: Fri, 17 Jul 2026 10:54:16 +0100 Subject: [PATCH 03/10] Fixed failing tests --- .../webapp/services/PropertyRegistrationServiceTests.kt | 9 +++++++++ .../webapp/urlProviders/LandlordDashboardUrlTests.kt | 1 + 2 files changed, 10 insertions(+) diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationServiceTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationServiceTests.kt index 55dc3a0fc1..1b5fb7753e 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationServiceTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationServiceTests.kt @@ -205,6 +205,7 @@ class PropertyRegistrationServiceTests { rentFrequency = rentFrequency, customRentFrequency = customRentFrequency, rentAmount = rentAmount, + licenseProvideLater = false, ), ).thenReturn(expectedPropertyOwnership) whenever(mockAbsoluteUrlProvider.buildLandlordDashboardUri()).thenReturn(URI("https:gov.uk")) @@ -248,6 +249,7 @@ class PropertyRegistrationServiceTests { rentFrequency = rentFrequency, customRentFrequency = customRentFrequency, rentAmount = rentAmount, + licenseProvideLater = false, ) verify(mockPropertyComplianceService).saveRegistrationComplianceData( registrationNumberValue = registrationNumber.number, @@ -298,6 +300,7 @@ class PropertyRegistrationServiceTests { rentAmount = anyOrNull(), customPropertyType = anyOrNull(), markedJointLandlord = any(), + licenseProvideLater = anyOrNull(), ), ).thenReturn(expectedPropertyOwnership) whenever(mockAbsoluteUrlProvider.buildLandlordDashboardUri()).thenReturn(URI("https:gov.uk")) @@ -388,6 +391,7 @@ class PropertyRegistrationServiceTests { rentAmount = anyOrNull(), customPropertyType = anyOrNull(), markedJointLandlord = any(), + licenseProvideLater = anyOrNull(), ), ).thenReturn(expectedPropertyOwnership) @@ -489,6 +493,7 @@ class PropertyRegistrationServiceTests { rentFrequency = rentFrequency, customRentFrequency = customRentFrequency, rentAmount = rentAmount, + licenseProvideLater = false, ), ).thenReturn(expectedPropertyOwnership) whenever(mockAbsoluteUrlProvider.buildLandlordDashboardUri()).thenReturn(URI("https:gov.uk")) @@ -530,6 +535,7 @@ class PropertyRegistrationServiceTests { rentFrequency = rentFrequency, customRentFrequency = customRentFrequency, rentAmount = rentAmount, + licenseProvideLater = false, ) } @@ -583,6 +589,7 @@ class PropertyRegistrationServiceTests { rentFrequency = RentFrequency.MONTHLY, customRentFrequency = null, rentAmount = 123.toBigDecimal(), + licenseProvideLater = false, ), ).thenReturn(expectedPropertyOwnership) whenever(mockAbsoluteUrlProvider.buildLandlordDashboardUri()).thenReturn(URI("https:gov.uk")) @@ -663,6 +670,7 @@ class PropertyRegistrationServiceTests { rentFrequency = RentFrequency.MONTHLY, customRentFrequency = null, rentAmount = 123.toBigDecimal(), + licenseProvideLater = false, ), ).thenReturn(expectedPropertyOwnership) whenever(mockAbsoluteUrlProvider.buildLandlordDashboardUri()).thenReturn(URI("https:gov.uk")) @@ -740,6 +748,7 @@ class PropertyRegistrationServiceTests { rentFrequency = RentFrequency.MONTHLY, customRentFrequency = null, rentAmount = 123.toBigDecimal(), + licenseProvideLater = false, ), ).thenReturn(expectedPropertyOwnership) whenever(mockAbsoluteUrlProvider.buildLandlordDashboardUri()).thenReturn(URI("https:gov.uk")) diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/urlProviders/LandlordDashboardUrlTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/urlProviders/LandlordDashboardUrlTests.kt index 8752af26d7..03825c5e41 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/urlProviders/LandlordDashboardUrlTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/urlProviders/LandlordDashboardUrlTests.kt @@ -201,6 +201,7 @@ class LandlordDashboardUrlTests( anyOrNull(), anyOrNull(), anyOrNull(), + anyOrNull(), ), ).thenReturn(propertyOwnership) From 41d3700c84f4841b74743367691970d7424f682a Mon Sep 17 00:00:00 2001 From: bnjn-mt Date: Fri, 17 Jul 2026 17:46:06 +0100 Subject: [PATCH 04/10] PDJB-990: Add licensing provide-later integration coverage --- .../PropertyDetailsUpdateJourneyTests.kt | 1722 ++----- .../PropertyRegistrationJourneyTests.kt | 4462 ++++++----------- .../PropertyRegistrationSinglePageTests.kt | 4282 +++++----------- .../pages/basePages/LicensingTypeFormPage.kt | 13 +- ...ensingLaterFormPagePropertyRegistration.kt | 21 + 5 files changed, 3539 insertions(+), 6961 deletions(-) create mode 100644 src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/pageObjects/pages/propertyRegistrationJourneyPages/ProvideLicensingLaterFormPagePropertyRegistration.kt diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyDetailsUpdateJourneyTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyDetailsUpdateJourneyTests.kt index 242545f442..e909325554 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyDetailsUpdateJourneyTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyDetailsUpdateJourneyTests.kt @@ -2,7 +2,6 @@ package uk.gov.communities.prsdb.webapp.integration import com.microsoft.playwright.Page import com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat -import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test import uk.gov.communities.prsdb.webapp.constants.PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING @@ -48,1240 +47,613 @@ class PropertyDetailsUpdateJourneyTests : IntegrationTestWithMutableData("data-l private val urlArguments = mapOf("propertyOwnershipId" to propertyOwnershipId.toString()) @Nested - inner class RestructureAndSkippingEnabled { - @BeforeEach - fun enableRestructureAndSkippingFlag() { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + inner class OwnershipTypeUpdates { + @Test + fun `A property can have its ownership type updated`(page: Page) { + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.ownershipTypeRow.clickFirstActionLinkAndWait() + val updateOwnershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update Ownership Type page + updateOwnershipTypePage.submitOwnershipType(OwnershipType.LEASEHOLD) + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.ownershipTypeRow.value).containsText("Leasehold") } + } - @Nested - inner class OwnershipTypeUpdates { - @Test - fun `A property can have its ownership type updated`(page: Page) { - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.ownershipTypeRow.clickFirstActionLinkAndWait() - val updateOwnershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyDetailsUpdate::class, urlArguments) + @Nested + inner class LicenceUpdates { + @Test + fun `A property can have its licensing updated to a selective licence`(page: Page) { + val newLicenceNumber = "SL123" + + // Details page + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to selective + updateLicensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) + val updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) + val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("Selective licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("Selective licence") + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) + } - // Update Ownership Type page - updateOwnershipTypePage.submitOwnershipType(OwnershipType.LEASEHOLD) - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + @Test + fun `A property can have its licensing updated to a HMO Mandatory licence`(page: Page) { + val newLicenceNumber = "MAND123" + + // Details page + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to HMO mandatory + updateLicensingTypePage.submitLicensingType(LicensingType.HMO_MANDATORY_LICENCE) + val updateLicenceNumberPage = assertPageIs(page, HmoMandatoryLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) + val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("HMO mandatory licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("HMO mandatory licence") + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) + } - // Check changes have occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.ownershipTypeRow.value).containsText("Leasehold") - } + @Test + fun `A property can have its licensing updated to a HMO additional licence`(page: Page) { + val newLicenceNumber = "ADD123" + + // Details page + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to HMO additional + updateLicensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) + val updateLicenceNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) + val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("HMO additional licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("HMO additional licence") + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) } - @Nested - inner class LicenceUpdates { - @Test - fun `A property can have its licensing updated to a selective licence`(page: Page) { - val newLicenceNumber = "SL123" + @Test + fun `A property can have its licensing removed`(page: Page) { + // A property ownership with an existing licence + val propertyOwnershipId = 7L + val urlArguments = mapOf("propertyOwnershipId" to propertyOwnershipId.toString()) + + // Details page + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to no licensing + updateLicensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) + val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have removed this property’s licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("None") + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("None") + } - // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + @Test + fun `Update licensing flow does not show provide this later action`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - // Update licence to selective - updateLicensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) - val updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + val propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) - val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + assertThat(updateLicensingTypePage.provideThisLaterButton).isHidden() + } - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("Selective licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + @Test + fun `A property can have its licensing number updated again from the check licensing answers page`(page: Page) { + val firstNewLicenceNumber = "SL456" + val secondNewLicenceNumber = "SL789" + + // Details page + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to selective + updateLicensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) + var updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(firstNewLicenceNumber) + var checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Click change link for Licensing Number + checkLicensingAnswersPage.summaryList.licensingNumberRow + .clickFirstActionLinkAndWait() + updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(secondNewLicenceNumber) + checkLicensingAnswersPage = + assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("Selective licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(secondNewLicenceNumber) + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("Selective licence") + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(secondNewLicenceNumber) + } + } - // Check changes have occurred - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("Selective licence") - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) - } + @Nested + inner class TenancyAndRentalInformation { + private val occupiedPropertyOwnershipId = 1L + private val occupiedPropertyUrlArguments = mapOf("propertyOwnershipId" to occupiedPropertyOwnershipId.toString()) - @Test - fun `A property can have its licensing updated to a HMO Mandatory licence`(page: Page) { - val newLicenceNumber = "MAND123" + private val vacantPropertyOwnershipId = 7L + private val vacantPropertyUrlArguments = mapOf("propertyOwnershipId" to vacantPropertyOwnershipId.toString()) + @Nested + inner class OccupancyUpdates { + @Test + fun `A property can have its occupancy updated from occupied to vacant`(page: Page) { // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to HMO mandatory - updateLicensingTypePage.submitLicensingType(LicensingType.HMO_MANDATORY_LICENCE) - val updateLicenceNumberPage = assertPageIs(page, HmoMandatoryLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) - val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("HMO mandatory licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.clickFirstActionLinkAndWait() + val updateOccupancyPage = assertPageIs(page, OccupancyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update occupancy to vacant + assertThat(updateOccupancyPage.form.fieldsetHeading).containsText("Update whether your property is occupied by tenants") + updateOccupancyPage.submitIsVacant() + val checkOccupancyAnswersPage = + assertPageIs(page, CheckOccupancyAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check occupancy answers + assertThat(checkOccupancyAnswersPage.summaryList.occupancyRow).containsText("No") + assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).isHidden() + assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).isHidden() + checkOccupancyAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) // Check changes have occurred - assertThat( - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value, - ).containsText("HMO mandatory licence") - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.value).containsText("No") } @Test - fun `A property can have its licensing updated to a HMO additional licence`(page: Page) { - val newLicenceNumber = "ADD123" - + fun `A property can have its occupancy updated from vacant to occupied`(page: Page) { // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to HMO additional - updateLicensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) - val updateLicenceNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) - val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("HMO additional licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(vacantPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.clickFirstActionLinkAndWait() + val updateOccupancyPage = assertPageIs(page, OccupancyFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update occupancy to occupied + assertThat(updateOccupancyPage.form.fieldsetHeading).containsText("Update whether your property is occupied by tenants") + updateOccupancyPage.submitIsOccupied() + val updateNumberOfHouseholdsPage = + assertPageIs(page, OccupancyNumberOfHouseholdsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update number of households + val newNumberOfHouseholds = 1 + assertThat(updateNumberOfHouseholdsPage.header).containsText("Update how many households live in your property") + updateNumberOfHouseholdsPage.submitNumberOfHouseholds(newNumberOfHouseholds) + val updateNumberOfPeoplePage = + assertPageIs(page, OccupancyNumberOfPeopleFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update number of people + val newNumberOfPeople = 3 + assertThat(updateNumberOfPeoplePage.header).containsText("Update how many people live in your property") + updateNumberOfPeoplePage.submitNumOfPeople(newNumberOfPeople) + val bedroomsPage = + assertPageIs(page, OccupancyNumberOfBedroomsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update number of bedrooms + val newNumberOfBedrooms = 3 + assertThat(bedroomsPage.header).containsText("Update how many bedrooms are in your property") + bedroomsPage.submitNumOfBedrooms(newNumberOfBedrooms) + val rentIncludesBillsPage = + assertPageIs(page, OccupancyRentIncludesBillsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update rent include bills + assertThat(rentIncludesBillsPage.form.fieldsetHeading).containsText("Update whether the rent includes bills") + rentIncludesBillsPage.submitIsIncluded() + val billsIncludedPage = + assertPageIs(page, OccupancyBillsIncludedFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update bills included + val expectedBillsIncluded = "Gas, Electricity, Water" + assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Update which of these you include in the rent") + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.form.submit() + val furnishedPage = + assertPageIs(page, OccupancyFurnishedStatusFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update furnished status + val expectedFurnishedStatus = "Furnished" + assertThat( + furnishedPage.form.fieldsetHeading, + ).containsText("Update is the property furnished") + furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) + val rentFrequencyPage = + assertPageIs(page, OccupancyRentFrequencyFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update rent frequency + val expectedRentFrequency = "Weekly" + assertThat(rentFrequencyPage.header).containsText("Update when you charge rent") + rentFrequencyPage.selectRentFrequency(RentFrequency.WEEKLY) + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, OccupancyRentAmountFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update rent amount + val expectedRentAmount = "£400" + assertThat(rentAmountPage.header).containsText("Update your weekly rent") + rentAmountPage.submitRentAmount("400") + val checkOccupancyAnswersPage = + assertPageIs(page, CheckOccupancyAnswersPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + // Check occupancy answers + assertThat(checkOccupancyAnswersPage.summaryList.occupancyRow).containsText("Yes") + assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText(newNumberOfHouseholds.toString()) + assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText(newNumberOfPeople.toString()) + assertThat(checkOccupancyAnswersPage.summaryList.numberOfBedroomsRow).containsText(newNumberOfBedrooms.toString()) + assertThat(checkOccupancyAnswersPage.summaryList.rentIncludesBillsRow).containsText("Yes") + assertThat(checkOccupancyAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) + assertThat(checkOccupancyAnswersPage.summaryList.furnishedStatusRow).containsText(expectedFurnishedStatus) + assertThat(checkOccupancyAnswersPage.summaryList.rentFrequencyRow).containsText(expectedRentFrequency) + assertThat(checkOccupancyAnswersPage.summaryList.rentAmountRow).containsText(expectedRentAmount) + checkOccupancyAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, vacantPropertyUrlArguments) // Check changes have occurred - assertThat( - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value, - ).containsText("HMO additional licence") - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.value).containsText("Yes") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.value) + .containsText(newNumberOfHouseholds.toString()) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfPeopleRow.value) + .containsText(newNumberOfPeople.toString()) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) + .containsText(newNumberOfBedrooms.toString()) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value).containsText("Yes") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow.value).containsText(expectedBillsIncluded) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value).containsText(expectedFurnishedStatus) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.value).containsText(expectedRentFrequency) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow.value).containsText(expectedRentAmount) } + } + @Nested + inner class HouseholdsAndTenantsUpdates { @Test - fun `A property can have its licensing removed`(page: Page) { - // A property ownership with an existing licence - val propertyOwnershipId = 7L - val urlArguments = mapOf("propertyOwnershipId" to propertyOwnershipId.toString()) - + fun `A property can have just their number of households and people updated`(page: Page) { // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to no licensing - updateLicensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) - val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have removed this property’s licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("None") - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.clickFirstActionLinkAndWait() + val updateNumberOfHouseholdsPage = + assertPageIs(page, NumberOfHouseholdsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update number of households + val newNumberOfHouseholds = 1 + assertThat(updateNumberOfHouseholdsPage.header).containsText("Update how many households live in your property") + updateNumberOfHouseholdsPage.submitNumberOfHouseholds(newNumberOfHouseholds) + val updateNumberOfPeoplePage = + assertPageIs(page, HouseholdsNumberOfPeopleFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update number of people + val newNumberOfPeople = 3 + assertThat(updateNumberOfPeoplePage.header).containsText("Update how many people live in your property") + updateNumberOfPeoplePage.submitNumOfPeople(newNumberOfPeople) + val checkOccupancyAnswersPage = + assertPageIs(page, CheckHouseholdsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check occupancy answers + assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText(newNumberOfHouseholds.toString()) + assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText(newNumberOfPeople.toString()) + checkOccupancyAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) // Check changes have occurred - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("None") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.value) + .containsText(newNumberOfHouseholds.toString()) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfPeopleRow.value) + .containsText(newNumberOfPeople.toString()) } @Test - fun `A property can have its licensing number updated again from the check licensing answers page`(page: Page) { - val firstNewLicenceNumber = "SL456" - val secondNewLicenceNumber = "SL789" - + fun `leading zeros are stripped from households and people on the CYA page`(page: Page) { // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to selective - updateLicensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) - var updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(firstNewLicenceNumber) - var checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Click change link for Licensing Number - checkLicensingAnswersPage.summaryList.licensingNumberRow - .clickFirstActionLinkAndWait() - updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(secondNewLicenceNumber) - checkLicensingAnswersPage = - assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("Selective licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(secondNewLicenceNumber) - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("Selective licence") - assertThat( - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value, - ).containsText(secondNewLicenceNumber) + val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.clickFirstActionLinkAndWait() + val updateNumberOfHouseholdsPage = + assertPageIs(page, NumberOfHouseholdsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Submit number of households with leading zeros + updateNumberOfHouseholdsPage.submitNumberOfHouseholds("003") + val updateNumberOfPeoplePage = + assertPageIs(page, HouseholdsNumberOfPeopleFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Submit number of people with leading zeros + updateNumberOfPeoplePage.submitNumOfPeople("007") + val checkOccupancyAnswersPage = + assertPageIs(page, CheckHouseholdsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check CYA page displays values without leading zeros + assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText("3") + assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText("7") } } @Nested - inner class TenancyAndRentalInformation { - private val occupiedPropertyOwnershipId = 1L - private val occupiedPropertyUrlArguments = mapOf("propertyOwnershipId" to occupiedPropertyOwnershipId.toString()) - - private val vacantPropertyOwnershipId = 7L - private val vacantPropertyUrlArguments = mapOf("propertyOwnershipId" to vacantPropertyOwnershipId.toString()) - - @Nested - inner class OccupancyUpdates { - @Test - fun `A property can have its occupancy updated from occupied to vacant`(page: Page) { - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.clickFirstActionLinkAndWait() - val updateOccupancyPage = - assertPageIs(page, OccupancyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update occupancy to vacant - assertThat(updateOccupancyPage.form.fieldsetHeading).containsText("Update whether your property is occupied by tenants") - updateOccupancyPage.submitIsVacant() - val checkOccupancyAnswersPage = - assertPageIs(page, CheckOccupancyAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check occupancy answers - assertThat(checkOccupancyAnswersPage.summaryList.occupancyRow).containsText("No") - assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).isHidden() - assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).isHidden() - checkOccupancyAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check changes have occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.value).containsText("No") - } - - @Test - fun `A property can have its occupancy updated from vacant to occupied`(page: Page) { - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(vacantPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.clickFirstActionLinkAndWait() - val updateOccupancyPage = assertPageIs(page, OccupancyFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update occupancy to occupied - assertThat(updateOccupancyPage.form.fieldsetHeading).containsText("Update whether your property is occupied by tenants") - updateOccupancyPage.submitIsOccupied() - val updateNumberOfHouseholdsPage = - assertPageIs(page, OccupancyNumberOfHouseholdsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update number of households - val newNumberOfHouseholds = 1 - assertThat(updateNumberOfHouseholdsPage.header).containsText("Households in your property") - updateNumberOfHouseholdsPage.submitNumberOfHouseholds(newNumberOfHouseholds) - val updateNumberOfPeoplePage = - assertPageIs(page, OccupancyNumberOfPeopleFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update number of people - val newNumberOfPeople = 3 - assertThat(updateNumberOfPeoplePage.header).containsText("Update how many people live in your property") - updateNumberOfPeoplePage.submitNumOfPeople(newNumberOfPeople) - val bedroomsPage = - assertPageIs(page, OccupancyNumberOfBedroomsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update number of bedrooms - val newNumberOfBedrooms = 3 - assertThat(bedroomsPage.header).containsText("Update how many bedrooms are in your property") - bedroomsPage.submitNumOfBedrooms(newNumberOfBedrooms) - val rentIncludesBillsPage = - assertPageIs(page, OccupancyRentIncludesBillsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update rent include bills - assertThat(rentIncludesBillsPage.form.fieldsetHeading).containsText("Update whether the rent includes bills") - rentIncludesBillsPage.submitIsIncluded() - val billsIncludedPage = - assertPageIs(page, OccupancyBillsIncludedFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update bills included - val expectedBillsIncluded = "Gas, Electricity, Water" - assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Update which of these you include in the rent") - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.form.submit() - val furnishedPage = - assertPageIs(page, OccupancyFurnishedStatusFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update furnished status - val expectedFurnishedStatus = "Furnished" - assertThat( - furnishedPage.form.fieldsetHeading, - ).containsText("Update is the property furnished") - furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) - val rentFrequencyPage = - assertPageIs(page, OccupancyRentFrequencyFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update rent frequency - val expectedRentFrequency = "Weekly" - assertThat(rentFrequencyPage.header).containsText("Update when you charge rent") - rentFrequencyPage.selectRentFrequency(RentFrequency.WEEKLY) - rentFrequencyPage.form.submit() - val rentAmountPage = - assertPageIs(page, OccupancyRentAmountFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update rent amount - val expectedRentAmount = "£400" - assertThat(rentAmountPage.header).containsText("Update your weekly rent") - rentAmountPage.submitRentAmount("400") - val checkOccupancyAnswersPage = - assertPageIs(page, CheckOccupancyAnswersPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - // Check occupancy answers - assertThat(checkOccupancyAnswersPage.summaryList.occupancyRow).containsText("Yes") - assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText(newNumberOfHouseholds.toString()) - assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText(newNumberOfPeople.toString()) - assertThat(checkOccupancyAnswersPage.summaryList.numberOfBedroomsRow).containsText(newNumberOfBedrooms.toString()) - assertThat(checkOccupancyAnswersPage.summaryList.rentIncludesBillsRow).containsText("Yes") - assertThat(checkOccupancyAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) - assertThat(checkOccupancyAnswersPage.summaryList.furnishedStatusRow).containsText(expectedFurnishedStatus) - assertThat(checkOccupancyAnswersPage.summaryList.rentFrequencyRow).containsText(expectedRentFrequency) - assertThat(checkOccupancyAnswersPage.summaryList.rentAmountRow).containsText(expectedRentAmount) - checkOccupancyAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, vacantPropertyUrlArguments) - - // Check changes have occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.value).containsText("Yes") - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.value) - .containsText(newNumberOfHouseholds.toString()) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfPeopleRow.value) - .containsText(newNumberOfPeople.toString()) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) - .containsText(newNumberOfBedrooms.toString()) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value).containsText("Yes") - assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow.value).containsText(expectedBillsIncluded) - assertThat( - propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value, - ).containsText(expectedFurnishedStatus) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.value).containsText(expectedRentFrequency) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow.value).containsText(expectedRentAmount) - } - } - - @Nested - inner class HouseholdsAndTenantsUpdates { - @Test - fun `A property can have just their number of households and people updated`(page: Page) { - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.clickFirstActionLinkAndWait() - val updateNumberOfHouseholdsPage = - assertPageIs(page, NumberOfHouseholdsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update number of households - val newNumberOfHouseholds = 1 - assertThat(updateNumberOfHouseholdsPage.header).containsText("Households in your property") - updateNumberOfHouseholdsPage.submitNumberOfHouseholds(newNumberOfHouseholds) - val updateNumberOfPeoplePage = - assertPageIs(page, HouseholdsNumberOfPeopleFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update number of people - val newNumberOfPeople = 3 - assertThat(updateNumberOfPeoplePage.header).containsText("Update how many people live in your property") - updateNumberOfPeoplePage.submitNumOfPeople(newNumberOfPeople) - val checkOccupancyAnswersPage = - assertPageIs(page, CheckHouseholdsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check occupancy answers - assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText(newNumberOfHouseholds.toString()) - assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText(newNumberOfPeople.toString()) - checkOccupancyAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check changes have occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.value) - .containsText(newNumberOfHouseholds.toString()) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfPeopleRow.value) - .containsText(newNumberOfPeople.toString()) - } - - @Test - fun `Leading zeros are stripped from households and people on the CYA page`(page: Page) { - // Details page - val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.clickFirstActionLinkAndWait() - val updateNumberOfHouseholdsPage = - assertPageIs(page, NumberOfHouseholdsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Submit number of households with leading zeros - updateNumberOfHouseholdsPage.submitNumberOfHouseholds("003") - val updateNumberOfPeoplePage = - assertPageIs(page, HouseholdsNumberOfPeopleFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Submit number of people with leading zeros - updateNumberOfPeoplePage.submitNumOfPeople("007") - val checkOccupancyAnswersPage = - assertPageIs(page, CheckHouseholdsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check CYA page displays values without leading zeros - assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText("3") - assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText("7") - } - } - - @Nested - inner class NumberOfBedroomsUpdates { - @Test - fun `A property can have just its number of bedrooms updated`(page: Page) { - val newNumberOfBedrooms = 4 - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - // Assert initial number of bedrooms is not 4 - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) - .not() - .containsText(newNumberOfBedrooms.toString()) - propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.clickFirstActionLinkAndWait() - val updateNumberOfBedroomsPage = - assertPageIs(page, NumberOfBedroomsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update number of bedrooms - assertThat(updateNumberOfBedroomsPage.header).containsText("Update how many bedrooms are in your property") - updateNumberOfBedroomsPage.submitNumOfBedrooms(newNumberOfBedrooms) - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check change has occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) - .containsText(newNumberOfBedrooms.toString()) - } - } - - @Nested - inner class RentIncludesBills { - @Test - fun `A property can have its rent includes bills status updated`(page: Page) { - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - // Assert initial rent includes bills status is not Yes - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) - .not() - .containsText("Yes") - propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() - val updateRentIncludesBillsPage = - assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update rent includes bills to yes - assertThat(updateRentIncludesBillsPage.form.fieldsetHeading).containsText("Update whether the rent includes bills") - updateRentIncludesBillsPage.submitIsIncluded() - val billsIncludedPage = - assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update bills included - val expectedBillsIncluded = "Gas, Electricity, Water" - assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Update which of these you include in the rent") - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.form.submit() - val checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check answers - assertThat(checkYourAnswersPage.summaryList.rentIncludesBillsRow).containsText("Yes") - assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) - checkYourAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) - .containsText("Yes") - assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow).containsText(expectedBillsIncluded) - } - - @Test - fun `Changing the rent includes bills status from the CYA page updates the property with the correct values`(page: Page) { - // start update journey - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() - var updateRentIncludesBillsPage = - assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - // Select yes for rent includes bills - updateRentIncludesBillsPage.submitIsIncluded() - val billsIncludedPage = - assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - // Select bills included and submit - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.form.submit() - var checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Change rent includes bills answer to no - checkYourAnswersPage.summaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() - updateRentIncludesBillsPage = - assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - updateRentIncludesBillsPage.submitIsNotIncluded() - checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Confirm answers - assertThat(checkYourAnswersPage.summaryList.rentIncludesBillsRow).containsText("No") - assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).isHidden() - checkYourAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check update is correct - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) - .containsText("No") - assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow).isHidden() - } - - @Test - fun `Changing the bills included answer from the CYA page updates the property with the correct values`(page: Page) { - // Start update journey and reach the CYA page with bills included set - val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() - val updateRentIncludesBillsPage = - assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - updateRentIncludesBillsPage.submitIsIncluded() - val initialBillsIncludedPage = - assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - initialBillsIncludedPage.selectGasElectricityWater() - initialBillsIncludedPage.form.submit() - var checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Click the change link on the bills included row - checkYourAnswersPage.summaryList.billsIncludedRow.clickFirstActionLinkAndWait() - val billsIncludedPage = - assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Change the selection and submit - billsIncludedPage.form.billsIncludedCheckboxes.checkCheckbox(BillsIncluded.COUNCIL_TAX.toString()) - billsIncludedPage.form.submit() - checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Confirm new value shown on CYA and persisted to property details - val expectedBillsIncluded = "Gas, Electricity, Water, Council Tax" - assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) - checkYourAnswersPage.confirm() - val updatedPropertyDetailsPage = - assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - assertThat(updatedPropertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow) - .containsText(expectedBillsIncluded) - } - } - - @Nested - inner class FurnishedStatusUpdates { - @Test - fun `A property can have just its furniture status updated`(page: Page) { - val newFurnishedStatusValue = "Partly furnished" - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - // Assert initial furnished status is not FurnishedStatus.PART_FURNISHED - assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value) - .not() - .containsText(newFurnishedStatusValue) - propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.clickFirstActionLinkAndWait() - val updateFurnishedStatusPage = - assertPageIs(page, FurnishedStatusFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update furnished status - val newFurnishedStatus = FurnishedStatus.PART_FURNISHED - assertThat(updateFurnishedStatusPage.form.fieldsetHeading) - .containsText("Update is the property furnished") - updateFurnishedStatusPage.submitFurnishedStatus(newFurnishedStatus) - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check change has occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value) - .containsText(newFurnishedStatusValue) - } - } - - @Nested - inner class RentFrequencyAndAmountUpdates { - @Test - fun `A property can have its rentFrequency and amount updated`(page: Page) { - val newRentFrequency = RentFrequency.WEEKLY - val newRentFrequencyDisplayName = "Weekly" - val newRentAmount = "200" - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - // Assert initial rent frequency is not newRentFrequency - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.value) - .not() - .containsText(newRentFrequencyDisplayName) - // Assert initial rent amount is not newRentAmount - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow.value) - .not() - .containsText(newRentAmount) - propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.clickFirstActionLinkAndWait() - val rentFrequencyPage = - assertPageIs(page, RentFrequencyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update rent frequency - assertThat(rentFrequencyPage.header).containsText("Update when you charge rent") - rentFrequencyPage.selectRentFrequency(newRentFrequency) - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update rent amount - assertThat(rentAmountPage.header).containsText("Update your weekly rent") - rentAmountPage.submitRentAmount(newRentAmount) - val checkYourAnswersPage = - assertPageIs(page, CheckRentFrequencyAndAmountAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check answers - assertThat(checkYourAnswersPage.summaryList.rentFrequencyRow).containsText(newRentFrequencyDisplayName) - assertThat(checkYourAnswersPage.summaryList.rentAmountRow).containsText(newRentAmount) - checkYourAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow).containsText(newRentFrequencyDisplayName) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow).containsText(newRentAmount) - } - - @Test - fun `Leading zeros are stripped from rent amount on the CYA page`(page: Page) { - // Details page - val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.clickFirstActionLinkAndWait() - val rentFrequencyPage = - assertPageIs(page, RentFrequencyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Submit any rent frequency - rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Submit rent amount with leading zeros - rentAmountPage.submitRentAmount("00500.50") - val checkYourAnswersPage = - assertPageIs(page, CheckRentFrequencyAndAmountAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check CYA page displays value without leading zeros - assertThat(checkYourAnswersPage.summaryList.rentAmountRow).containsText("£500.50") - } - } - } - } - - // TODO PDJB-1340: Remove tests when the PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING Feature Flag is removed - @Nested - inner class RestructureAndSkippingDisabled { - @BeforeEach - fun disableRestructureAndSkippingFlag() { - featureFlagManager.disableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - } - - @Nested - inner class OwnershipTypeUpdates { + inner class NumberOfBedroomsUpdates { @Test - fun `A property can have its ownership type updated`(page: Page) { + fun `A property can have just its number of bedrooms updated`(page: Page) { + val newNumberOfBedrooms = 4 // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.ownershipTypeRow.clickFirstActionLinkAndWait() - val updateOwnershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update Ownership Type page - updateOwnershipTypePage.submitOwnershipType(OwnershipType.LEASEHOLD) - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.ownershipTypeRow.value).containsText("Leasehold") + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + // Assert initial number of bedrooms is not 4 + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) + .not() + .containsText(newNumberOfBedrooms.toString()) + propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.clickFirstActionLinkAndWait() + val updateNumberOfBedroomsPage = + assertPageIs(page, NumberOfBedroomsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update number of bedrooms + assertThat(updateNumberOfBedroomsPage.header).containsText("Update how many bedrooms are in your property") + updateNumberOfBedroomsPage.submitNumOfBedrooms(newNumberOfBedrooms) + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check change has occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) + .containsText(newNumberOfBedrooms.toString()) } } @Nested - inner class LicenceUpdates { - @Test - fun `A property can have its licensing updated to a selective licence`(page: Page) { - val newLicenceNumber = "SL123" - - // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to selective - updateLicensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) - val updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) - val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("Selective licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("Selective licence") - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) - } - + inner class RentIncludesBills { @Test - fun `A property can have its licensing updated to a HMO Mandatory licence`(page: Page) { - val newLicenceNumber = "MAND123" - + fun `A property can have its rent includes bills status updated`(page: Page) { // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to HMO mandatory - updateLicensingTypePage.submitLicensingType(LicensingType.HMO_MANDATORY_LICENCE) - val updateLicenceNumberPage = assertPageIs(page, HmoMandatoryLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) - val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("HMO mandatory licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat( - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value, - ).containsText("HMO mandatory licence") - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + // Assert initial rent includes bills status is not Yes + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) + .not() + .containsText("Yes") + propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() + val updateRentIncludesBillsPage = + assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update rent includes bills to yes + assertThat(updateRentIncludesBillsPage.form.fieldsetHeading).containsText("Update whether the rent includes bills") + updateRentIncludesBillsPage.submitIsIncluded() + val billsIncludedPage = + assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update bills included + val expectedBillsIncluded = "Gas, Electricity, Water" + assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Update which of these you include in the rent") + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.form.submit() + val checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check answers + assertThat(checkYourAnswersPage.summaryList.rentIncludesBillsRow).containsText("Yes") + assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) + checkYourAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) + .containsText("Yes") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow).containsText(expectedBillsIncluded) } @Test - fun `A property can have its licensing updated to a HMO additional licence`(page: Page) { - val newLicenceNumber = "ADD123" - - // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to HMO additional - updateLicensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) - val updateLicenceNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) - val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("HMO additional licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat( - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value, - ).containsText("HMO additional licence") - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) + fun `Changing the rent includes bills status from the CYA page updates the property with the correct values`(page: Page) { + // start update journey + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() + var updateRentIncludesBillsPage = + assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + // Select yes for rent includes bills + updateRentIncludesBillsPage.submitIsIncluded() + val billsIncludedPage = + assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + // Select bills included and submit + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.form.submit() + var checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Change rent includes bills answer to no + checkYourAnswersPage.summaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() + updateRentIncludesBillsPage = + assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + updateRentIncludesBillsPage.submitIsNotIncluded() + checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Confirm answers + assertThat(checkYourAnswersPage.summaryList.rentIncludesBillsRow).containsText("No") + assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).isHidden() + checkYourAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check update is correct + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) + .containsText("No") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow).isHidden() } @Test - fun `A property can have its licensing removed`(page: Page) { - // A property ownership with an existing licence - val propertyOwnershipId = 7L - val urlArguments = mapOf("propertyOwnershipId" to propertyOwnershipId.toString()) - - // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to no licensing - updateLicensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) - val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have removed this property’s licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("None") - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("None") + fun `Changing the bills included answer from the CYA page updates the property with the correct values`(page: Page) { + // Start update journey and reach the CYA page with bills included set + val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() + val updateRentIncludesBillsPage = + assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + updateRentIncludesBillsPage.submitIsIncluded() + val initialBillsIncludedPage = + assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + initialBillsIncludedPage.selectGasElectricityWater() + initialBillsIncludedPage.form.submit() + var checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Click the change link on the bills included row + checkYourAnswersPage.summaryList.billsIncludedRow.clickFirstActionLinkAndWait() + val billsIncludedPage = + assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Change the selection and submit + billsIncludedPage.form.billsIncludedCheckboxes.checkCheckbox(BillsIncluded.COUNCIL_TAX.toString()) + billsIncludedPage.form.submit() + checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Confirm new value shown on CYA and persisted to property details + val expectedBillsIncluded = "Gas, Electricity, Water, Council Tax" + assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) + checkYourAnswersPage.confirm() + val updatedPropertyDetailsPage = + assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + assertThat(updatedPropertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow) + .containsText(expectedBillsIncluded) } + } + @Nested + inner class FurnishedStatusUpdates { @Test - fun `A property can have its licensing number updated again from the check licensing answers page`(page: Page) { - val firstNewLicenceNumber = "SL456" - val secondNewLicenceNumber = "SL789" - + fun `A property can have just its furniture status updated`(page: Page) { + val newFurnishedStatusValue = "Partly furnished" // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to selective - updateLicensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) - var updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(firstNewLicenceNumber) - var checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Click change link for Licensing Number - checkLicensingAnswersPage.summaryList.licensingNumberRow - .clickFirstActionLinkAndWait() - updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(secondNewLicenceNumber) - checkLicensingAnswersPage = - assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("Selective licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(secondNewLicenceNumber) - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("Selective licence") - assertThat( - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value, - ).containsText(secondNewLicenceNumber) + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + // Assert initial furnished status is not FurnishedStatus.PART_FURNISHED + assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value) + .not() + .containsText(newFurnishedStatusValue) + propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.clickFirstActionLinkAndWait() + val updateFurnishedStatusPage = + assertPageIs(page, FurnishedStatusFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update furnished status + val newFurnishedStatus = FurnishedStatus.PART_FURNISHED + assertThat(updateFurnishedStatusPage.form.fieldsetHeading) + .containsText("Update is the property furnished") + updateFurnishedStatusPage.submitFurnishedStatus(newFurnishedStatus) + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check change has occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value) + .containsText(newFurnishedStatusValue) } } @Nested - inner class TenancyAndRentalInformation { - private val occupiedPropertyOwnershipId = 1L - private val occupiedPropertyUrlArguments = mapOf("propertyOwnershipId" to occupiedPropertyOwnershipId.toString()) - - private val vacantPropertyOwnershipId = 7L - private val vacantPropertyUrlArguments = mapOf("propertyOwnershipId" to vacantPropertyOwnershipId.toString()) - - @Nested - inner class OccupancyUpdates { - @Test - fun `A property can have its occupancy updated from occupied to vacant`(page: Page) { - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.clickFirstActionLinkAndWait() - val updateOccupancyPage = - assertPageIs(page, OccupancyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update occupancy to vacant - assertThat(updateOccupancyPage.form.fieldsetHeading).containsText("Update whether your property is occupied by tenants") - updateOccupancyPage.submitIsVacant() - val checkOccupancyAnswersPage = - assertPageIs(page, CheckOccupancyAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check occupancy answers - assertThat(checkOccupancyAnswersPage.summaryList.occupancyRow).containsText("No") - assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).isHidden() - assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).isHidden() - checkOccupancyAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check changes have occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.value).containsText("No") - } - - @Test - fun `A property can have its occupancy updated from vacant to occupied`(page: Page) { - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(vacantPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.clickFirstActionLinkAndWait() - val updateOccupancyPage = assertPageIs(page, OccupancyFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update occupancy to occupied - assertThat(updateOccupancyPage.form.fieldsetHeading).containsText("Update whether your property is occupied by tenants") - updateOccupancyPage.submitIsOccupied() - val updateNumberOfHouseholdsPage = - assertPageIs(page, OccupancyNumberOfHouseholdsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update number of households - val newNumberOfHouseholds = 1 - assertThat(updateNumberOfHouseholdsPage.header).containsText("Update how many households live in your property") - updateNumberOfHouseholdsPage.submitNumberOfHouseholds(newNumberOfHouseholds) - val updateNumberOfPeoplePage = - assertPageIs(page, OccupancyNumberOfPeopleFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update number of people - val newNumberOfPeople = 3 - assertThat(updateNumberOfPeoplePage.header).containsText("Update how many people live in your property") - updateNumberOfPeoplePage.submitNumOfPeople(newNumberOfPeople) - val bedroomsPage = - assertPageIs(page, OccupancyNumberOfBedroomsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update number of bedrooms - val newNumberOfBedrooms = 3 - assertThat(bedroomsPage.header).containsText("Update how many bedrooms are in your property") - bedroomsPage.submitNumOfBedrooms(newNumberOfBedrooms) - val rentIncludesBillsPage = - assertPageIs(page, OccupancyRentIncludesBillsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update rent include bills - assertThat(rentIncludesBillsPage.form.fieldsetHeading).containsText("Update whether the rent includes bills") - rentIncludesBillsPage.submitIsIncluded() - val billsIncludedPage = - assertPageIs(page, OccupancyBillsIncludedFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update bills included - val expectedBillsIncluded = "Gas, Electricity, Water" - assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Update which of these you include in the rent") - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.form.submit() - val furnishedPage = - assertPageIs(page, OccupancyFurnishedStatusFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update furnished status - val expectedFurnishedStatus = "Furnished" - assertThat( - furnishedPage.form.fieldsetHeading, - ).containsText("Update is the property furnished") - furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) - val rentFrequencyPage = - assertPageIs(page, OccupancyRentFrequencyFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update rent frequency - val expectedRentFrequency = "Weekly" - assertThat(rentFrequencyPage.header).containsText("Update when you charge rent") - rentFrequencyPage.selectRentFrequency(RentFrequency.WEEKLY) - rentFrequencyPage.form.submit() - val rentAmountPage = - assertPageIs(page, OccupancyRentAmountFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update rent amount - val expectedRentAmount = "£400" - assertThat(rentAmountPage.header).containsText("Update your weekly rent") - rentAmountPage.submitRentAmount("400") - val checkOccupancyAnswersPage = - assertPageIs(page, CheckOccupancyAnswersPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - // Check occupancy answers - assertThat(checkOccupancyAnswersPage.summaryList.occupancyRow).containsText("Yes") - assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText(newNumberOfHouseholds.toString()) - assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText(newNumberOfPeople.toString()) - assertThat(checkOccupancyAnswersPage.summaryList.numberOfBedroomsRow).containsText(newNumberOfBedrooms.toString()) - assertThat(checkOccupancyAnswersPage.summaryList.rentIncludesBillsRow).containsText("Yes") - assertThat(checkOccupancyAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) - assertThat(checkOccupancyAnswersPage.summaryList.furnishedStatusRow).containsText(expectedFurnishedStatus) - assertThat(checkOccupancyAnswersPage.summaryList.rentFrequencyRow).containsText(expectedRentFrequency) - assertThat(checkOccupancyAnswersPage.summaryList.rentAmountRow).containsText(expectedRentAmount) - checkOccupancyAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, vacantPropertyUrlArguments) - - // Check changes have occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.value).containsText("Yes") - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.value) - .containsText(newNumberOfHouseholds.toString()) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfPeopleRow.value) - .containsText(newNumberOfPeople.toString()) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) - .containsText(newNumberOfBedrooms.toString()) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value).containsText("Yes") - assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow.value).containsText(expectedBillsIncluded) - assertThat( - propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value, - ).containsText(expectedFurnishedStatus) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.value).containsText(expectedRentFrequency) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow.value).containsText(expectedRentAmount) - } - } - - @Nested - inner class HouseholdsAndTenantsUpdates { - @Test - fun `A property can have just their number of households and people updated`(page: Page) { - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.clickFirstActionLinkAndWait() - val updateNumberOfHouseholdsPage = - assertPageIs(page, NumberOfHouseholdsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update number of households - val newNumberOfHouseholds = 1 - assertThat(updateNumberOfHouseholdsPage.header).containsText("Update how many households live in your property") - updateNumberOfHouseholdsPage.submitNumberOfHouseholds(newNumberOfHouseholds) - val updateNumberOfPeoplePage = - assertPageIs(page, HouseholdsNumberOfPeopleFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update number of people - val newNumberOfPeople = 3 - assertThat(updateNumberOfPeoplePage.header).containsText("Update how many people live in your property") - updateNumberOfPeoplePage.submitNumOfPeople(newNumberOfPeople) - val checkOccupancyAnswersPage = - assertPageIs(page, CheckHouseholdsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check occupancy answers - assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText(newNumberOfHouseholds.toString()) - assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText(newNumberOfPeople.toString()) - checkOccupancyAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check changes have occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.value) - .containsText(newNumberOfHouseholds.toString()) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfPeopleRow.value) - .containsText(newNumberOfPeople.toString()) - } - - @Test - fun `leading zeros are stripped from households and people on the CYA page`(page: Page) { - // Details page - val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.clickFirstActionLinkAndWait() - val updateNumberOfHouseholdsPage = - assertPageIs(page, NumberOfHouseholdsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Submit number of households with leading zeros - updateNumberOfHouseholdsPage.submitNumberOfHouseholds("003") - val updateNumberOfPeoplePage = - assertPageIs(page, HouseholdsNumberOfPeopleFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Submit number of people with leading zeros - updateNumberOfPeoplePage.submitNumOfPeople("007") - val checkOccupancyAnswersPage = - assertPageIs(page, CheckHouseholdsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check CYA page displays values without leading zeros - assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText("3") - assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText("7") - } - } - - @Nested - inner class NumberOfBedroomsUpdates { - @Test - fun `A property can have just its number of bedrooms updated`(page: Page) { - val newNumberOfBedrooms = 4 - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - // Assert initial number of bedrooms is not 4 - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) - .not() - .containsText(newNumberOfBedrooms.toString()) - propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.clickFirstActionLinkAndWait() - val updateNumberOfBedroomsPage = - assertPageIs(page, NumberOfBedroomsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update number of bedrooms - assertThat(updateNumberOfBedroomsPage.header).containsText("Update how many bedrooms are in your property") - updateNumberOfBedroomsPage.submitNumOfBedrooms(newNumberOfBedrooms) - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check change has occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) - .containsText(newNumberOfBedrooms.toString()) - } - } - - @Nested - inner class RentIncludesBills { - @Test - fun `A property can have its rent includes bills status updated`(page: Page) { - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - // Assert initial rent includes bills status is not Yes - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) - .not() - .containsText("Yes") - propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() - val updateRentIncludesBillsPage = - assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update rent includes bills to yes - assertThat(updateRentIncludesBillsPage.form.fieldsetHeading).containsText("Update whether the rent includes bills") - updateRentIncludesBillsPage.submitIsIncluded() - val billsIncludedPage = - assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update bills included - val expectedBillsIncluded = "Gas, Electricity, Water" - assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Update which of these you include in the rent") - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.form.submit() - val checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check answers - assertThat(checkYourAnswersPage.summaryList.rentIncludesBillsRow).containsText("Yes") - assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) - checkYourAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) - .containsText("Yes") - assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow).containsText(expectedBillsIncluded) - } - - @Test - fun `Changing the rent includes bills status from the CYA page updates the property with the correct values`(page: Page) { - // start update journey - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() - var updateRentIncludesBillsPage = - assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - // Select yes for rent includes bills - updateRentIncludesBillsPage.submitIsIncluded() - val billsIncludedPage = - assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - // Select bills included and submit - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.form.submit() - var checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Change rent includes bills answer to no - checkYourAnswersPage.summaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() - updateRentIncludesBillsPage = - assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - updateRentIncludesBillsPage.submitIsNotIncluded() - checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Confirm answers - assertThat(checkYourAnswersPage.summaryList.rentIncludesBillsRow).containsText("No") - assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).isHidden() - checkYourAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check update is correct - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) - .containsText("No") - assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow).isHidden() - } - - @Test - fun `Changing the bills included answer from the CYA page updates the property with the correct values`(page: Page) { - // Start update journey and reach the CYA page with bills included set - val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() - val updateRentIncludesBillsPage = - assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - updateRentIncludesBillsPage.submitIsIncluded() - val initialBillsIncludedPage = - assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - initialBillsIncludedPage.selectGasElectricityWater() - initialBillsIncludedPage.form.submit() - var checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Click the change link on the bills included row - checkYourAnswersPage.summaryList.billsIncludedRow.clickFirstActionLinkAndWait() - val billsIncludedPage = - assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Change the selection and submit - billsIncludedPage.form.billsIncludedCheckboxes.checkCheckbox(BillsIncluded.COUNCIL_TAX.toString()) - billsIncludedPage.form.submit() - checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Confirm new value shown on CYA and persisted to property details - val expectedBillsIncluded = "Gas, Electricity, Water, Council Tax" - assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) - checkYourAnswersPage.confirm() - val updatedPropertyDetailsPage = - assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - assertThat(updatedPropertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow) - .containsText(expectedBillsIncluded) - } - } - - @Nested - inner class FurnishedStatusUpdates { - @Test - fun `A property can have just its furniture status updated`(page: Page) { - val newFurnishedStatusValue = "Partly furnished" - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - // Assert initial furnished status is not FurnishedStatus.PART_FURNISHED - assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value) - .not() - .containsText(newFurnishedStatusValue) - propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.clickFirstActionLinkAndWait() - val updateFurnishedStatusPage = - assertPageIs(page, FurnishedStatusFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update furnished status - val newFurnishedStatus = FurnishedStatus.PART_FURNISHED - assertThat(updateFurnishedStatusPage.form.fieldsetHeading) - .containsText("Update is the property furnished") - updateFurnishedStatusPage.submitFurnishedStatus(newFurnishedStatus) - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check change has occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value) - .containsText(newFurnishedStatusValue) - } + inner class RentFrequencyAndAmountUpdates { + @Test + fun `A property can have its rentFrequency and amount updated`(page: Page) { + val newRentFrequency = RentFrequency.WEEKLY + val newRentFrequencyDisplayName = "Weekly" + val newRentAmount = "200" + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + // Assert initial rent frequency is not newRentFrequency + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.value) + .not() + .containsText(newRentFrequencyDisplayName) + // Assert initial rent amount is not newRentAmount + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow.value) + .not() + .containsText(newRentAmount) + propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.clickFirstActionLinkAndWait() + val rentFrequencyPage = + assertPageIs(page, RentFrequencyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update rent frequency + assertThat(rentFrequencyPage.header).containsText("Update when you charge rent") + rentFrequencyPage.selectRentFrequency(newRentFrequency) + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update rent amount + assertThat(rentAmountPage.header).containsText("Update your weekly rent") + rentAmountPage.submitRentAmount(newRentAmount) + val checkYourAnswersPage = + assertPageIs(page, CheckRentFrequencyAndAmountAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check answers + assertThat(checkYourAnswersPage.summaryList.rentFrequencyRow).containsText(newRentFrequencyDisplayName) + assertThat(checkYourAnswersPage.summaryList.rentAmountRow).containsText(newRentAmount) + checkYourAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow).containsText(newRentFrequencyDisplayName) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow).containsText(newRentAmount) } - @Nested - inner class RentFrequencyAndAmountUpdates { - @Test - fun `A property can have its rentFrequency and amount updated`(page: Page) { - val newRentFrequency = RentFrequency.WEEKLY - val newRentFrequencyDisplayName = "Weekly" - val newRentAmount = "200" - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - // Assert initial rent frequency is not newRentFrequency - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.value) - .not() - .containsText(newRentFrequencyDisplayName) - // Assert initial rent amount is not newRentAmount - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow.value) - .not() - .containsText(newRentAmount) - propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.clickFirstActionLinkAndWait() - val rentFrequencyPage = - assertPageIs(page, RentFrequencyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update rent frequency - assertThat(rentFrequencyPage.header).containsText("Update when you charge rent") - rentFrequencyPage.selectRentFrequency(newRentFrequency) - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update rent amount - assertThat(rentAmountPage.header).containsText("Update your weekly rent") - rentAmountPage.submitRentAmount(newRentAmount) - val checkYourAnswersPage = - assertPageIs(page, CheckRentFrequencyAndAmountAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check answers - assertThat(checkYourAnswersPage.summaryList.rentFrequencyRow).containsText(newRentFrequencyDisplayName) - assertThat(checkYourAnswersPage.summaryList.rentAmountRow).containsText(newRentAmount) - checkYourAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow).containsText(newRentFrequencyDisplayName) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow).containsText(newRentAmount) - } - - @Test - fun `leading zeros are stripped from rent amount on the CYA page`(page: Page) { - // Details page - val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.clickFirstActionLinkAndWait() - val rentFrequencyPage = - assertPageIs(page, RentFrequencyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Submit any rent frequency - rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Submit rent amount with leading zeros - rentAmountPage.submitRentAmount("00500.50") - val checkYourAnswersPage = - assertPageIs(page, CheckRentFrequencyAndAmountAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check CYA page displays value without leading zeros - assertThat(checkYourAnswersPage.summaryList.rentAmountRow).containsText("£500.50") - } + @Test + fun `leading zeros are stripped from rent amount on the CYA page`(page: Page) { + // Details page + val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.clickFirstActionLinkAndWait() + val rentFrequencyPage = + assertPageIs(page, RentFrequencyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Submit any rent frequency + rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Submit rent amount with leading zeros + rentAmountPage.submitRentAmount("00500.50") + val checkYourAnswersPage = + assertPageIs(page, CheckRentFrequencyAndAmountAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check CYA page displays value without leading zeros + assertThat(checkYourAnswersPage.summaryList.rentAmountRow).containsText("£500.50") } } } diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt index 8d0fbf81d0..d28e39699b 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt @@ -8,7 +8,6 @@ import kotlinx.datetime.plus import kotlinx.datetime.toJavaLocalDate import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test import org.mockito.ArgumentCaptor.captor import org.mockito.kotlin.any @@ -88,6 +87,7 @@ import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyReg import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.ProvideElectricalCertLaterFormPagePropertyRegistration import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.ProvideEpcLaterFormPagePropertyRegistration import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.ProvideGasCertLaterFormPagePropertyRegistration +import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.ProvideLicensingLaterFormPagePropertyRegistration import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.RegisterPropertyStartPage import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.RemoveElectricalCertUploadFormPagePropertyRegistration import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.RemoveGasCertUploadFormPagePropertyRegistration @@ -116,13 +116,7 @@ import kotlin.test.assertTrue class PropertyRegistrationJourneyTests : IntegrationTestWithMutableData("data-local.sql") { private val absoluteLandlordUrl = "www.prsd.gov.uk/landlord" - private val propertyDetailsSectionHeader = "Property details" - private val ownershipSectionHeader = "Ownership and landlords" - private val occupiedSectionHeader = "Tell us if your property’s occupied" - private val licenseSectionHeader = "Tell us if your property needs a license" - private val gasSafetyHeader = "Gas safety certificate" - private val electricalSafetyHeader = "Electrical safety certificate" - private val epcSectionHeader = "Energy performance certificate (EPC)" + private val propertyRegistrationSectionHeader = "Section 1 of 2 — Add property details" @MockitoSpyBean private lateinit var propertyOwnershipRepository: PropertyOwnershipRepository @@ -154,1542 +148,1554 @@ class PropertyRegistrationJourneyTests : IntegrationTestWithMutableData("data-lo whenever( absoluteUrlProvider.buildPropertyDetailsUri(any()), ).thenReturn(URI("http://localhost/property-details/1")) + // The restructure flag is enabled by default in the integration config. Existing tests exercise the + // legacy journey, so disable it here; the restructured tests re-enable it explicitly in their bodies. + featureFlagManager.disableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) } - @Nested - inner class RestructureAndSkippingEnabled { - @BeforeEach - fun enableRestructureAndSkippingFlag() { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - } - - @Test - @Suppress("ktlint:standard:max-line-length") - fun `User can navigate the whole journey if pages are correctly filled in (select address, non-custom property type, selective license, occupied, compliance certificates uploaded)`( - page: Page, - ) { - // Start page (not a journey step, but it is how the user accesses the journey) - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - assertThat(registerPropertyStartPage.heading).containsText("Register a property") - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // Task list page (part of the journey to support redirects) - taskListPage.clickAboutYourPropertyTaskWithName("Property details") - val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - - // Address lookup - render page - assertThat(addressLookupPage.form.fieldsetHeading).containsText("What is the property address?") - assertThat(addressLookupPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) - // fill in and submit - addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") - val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) - - // Select address - render page - assertThat(selectAddressPage.form.fieldsetHeading).containsText("Select your address") - assertThat(selectAddressPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) - // fill in and submit - selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") - val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) - - // Verify incomplete property is created at this point - verify(landlordIncompletePropertiesRepository).save(any()) - - // Property type selection - render page - assertThat(propertyTypePage.form.fieldsetHeading).containsText("What type of property are you registering?") - assertThat(propertyTypePage.form.sectionHeader).containsText(propertyDetailsSectionHeader) - // fill in and submit - propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) - val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) - - // Number of bedrooms - render page - assertThat(bedroomsPage.header).containsText("How many bedrooms in your property?") - assertThat(bedroomsPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) - bedroomsPage.submitNumOfBedrooms(3) - val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) - - // Ownership type selection - render page - assertThat(ownershipTypePage.form.fieldsetHeading).containsText("Select the type of ownership you have for your property") - assertThat(ownershipTypePage.form.sectionHeader).containsText(ownershipSectionHeader) - // fill in and submit - ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) - val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - - // Has Joint Landlords - render page - assertThat(hasJointLandlordsPage.header).containsText("Invite joint landlords") - assertThat(hasJointLandlordsPage.sectionHeader).containsText(ownershipSectionHeader) - - // fill in and submit - hasJointLandlordsPage.submitHasJointLandlords() - val inviteJointLandlordPage = assertPageIs(page, InviteJointLandlordFormPagePropertyRegistration::class) - - // Invite joint landlord - render page - assertThat(inviteJointLandlordPage.heading).containsText("Invite a joint landlord to this property") - assertThat(inviteJointLandlordPage.form.sectionHeader).containsText(ownershipSectionHeader) - - // fill in and submit - inviteJointLandlordPage.submitEmail("email@address.com") - var checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordsPage.sectionHeader).containsText(ownershipSectionHeader) - assertThat(checkJointLandlordsPage.summaryList.firstRow.value).containsText("email@address.com") - - // Check joint landlords - render page - checkJointLandlordsPage - .form - .addAnotherButton - .clickAndWait() - - // Invite another joint landlord - render page - val addAnotherPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - assertThat(addAnotherPage.form.sectionHeader).containsText(ownershipSectionHeader) - addAnotherPage.submitEmail("email2@address.com") - - checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordsPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - - // Remove Joint Landlord - render page - val removeJointLandlordsPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordsPage.submitWantsToProceed() - - checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordsPage.form.submit() - val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - - // Occupancy - render page - assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") - assertThat(occupancyPage.form.sectionHeader).containsText(occupiedSectionHeader) - occupancyPage.submitIsOccupied() - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - - // Licensing type - render page - assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") - assertThat(licensingTypePage.form.sectionHeader).containsText(licenseSectionHeader) - licensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) - val selectiveLicencePage = assertPageIs(page, SelectiveLicenceFormPagePropertyRegistration::class) - - // Selective licence - render page - assertThat(selectiveLicencePage.form.fieldsetHeading).containsText("What is your selective licence number?") - assertThat(selectiveLicencePage.form.sectionHeader).containsText(licenseSectionHeader) - selectiveLicencePage.submitLicenseNumber("licence number") - - val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - - // Has Gas Supply - render page - assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) - assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert - render page - assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) - assertThat(hasGasCertPage.heading).containsText("Do you have a gas safety certificate for this property?") - hasGasCertPage.submitHasCertificate() - val gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page - assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(gasSafetyHeader) - assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") - gasCertIssueDatePage.submitDate(validGasSafetyCertIssueDate) - var uploadGasCertPage = assertPageIs(page, UploadGasCertFormPagePropertyRegistration::class) - - // Upload Gas Cert - render page - assertThat(uploadGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) - uploadGasCertPage.uploadGasCertificate(Path.of("src/test/resources/test-files/blank.png")) - var checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) - - // Check Gas Cert Uploads - render page - assertThat(checkGasCertUploadsPage.sectionHeader).containsText(gasSafetyHeader) - assertThat(checkGasCertUploadsPage.heading).containsText("You’ve uploaded 1 file") - assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - assertEquals(checkGasCertUploadsPage.table.rows.count(), 1) - checkGasCertUploadsPage.form.addAnotherButton.clickAndWait() - uploadGasCertPage = assertPageIs(page, UploadGasCertFormPagePropertyRegistration::class) - - uploadGasCertPage.uploadGasCertificate(Path.of("src/test/resources/test-files/blank.png")) - checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) - - assertThat(checkGasCertUploadsPage.heading).containsText("You’ve uploaded 2 files") - assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - assertThat(checkGasCertUploadsPage.table.getCell(1, 0)).containsText("blank.png") - assertEquals(checkGasCertUploadsPage.table.rows.count(), 2) - - checkGasCertUploadsPage.table - .getClickableCell(0, 2) - .link - .clickAndWait() - - val removeGasCertUploadPage = assertPageIs(page, RemoveGasCertUploadFormPagePropertyRegistration::class) - - removeGasCertUploadPage.form.radios.selectValue("true") - removeGasCertUploadPage.form.submit() - - checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) - assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - - assertEquals(checkGasCertUploadsPage.table.rows.count(), 1) - checkGasCertUploadsPage.form.submit() - - // Remove Gas Cert Upload - render page - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.sectionHeader).isHidden() - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasEic() - val electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date - render page - assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(electricalSafetyHeader) - assertThat( - electricalCertExpiryDatePage.heading, - ).containsText("What’s the expiry date on the Electrical Installation Certificate?") - electricalCertExpiryDatePage.submitDate(validExpiryDate) - var uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) - - // Upload Electrical Cert - render page - assertThat(uploadElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) - uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) - var checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) - - // Check Electrical Cert Uploads - render page - assertThat(checkElectricalCertUploadsPage.sectionHeader).containsText(electricalSafetyHeader) - assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 1) - checkElectricalCertUploadsPage.form.addAnotherButton.clickAndWait() - uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) - - uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) - checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) - assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - assertThat(checkElectricalCertUploadsPage.table.getCell(1, 0)).containsText("blank.png") - assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 2) - - checkElectricalCertUploadsPage.table - .getClickableCell(0, 2) - .link - .clickAndWait() - - val removeElectricalCertUploadPage = assertPageIs(page, RemoveElectricalCertUploadFormPagePropertyRegistration::class) - - removeElectricalCertUploadPage.form.radios.selectValue("true") - removeElectricalCertUploadPage.form.submit() - - checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) - assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - - assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 1) - checkElectricalCertUploadsPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep being able to find an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)) - .thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - expiryDate = validExpiryDate, - ), - ) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.sectionHeader).isHidden() - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // EpcLookupByUprnStep finds the EPC, so redirects to Check UPRN matched EPC - taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") - val confirmUprnMatchedEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) - - // Confirm UPRN matched EPC - submit No (don't use this EPC) - assertThat(confirmUprnMatchedEpcDetailsPage.sectionHeader).containsText(epcSectionHeader) - confirmUprnMatchedEpcDetailsPage.submitNo() - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(epcSectionHeader) - hasEpcPage.submitHasEpc() - val findYourEpcPage = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) - - // EPC Search - render page - assertThat(findYourEpcPage.form.sectionHeader).containsText(epcSectionHeader) - whenever(epcRegisterClient.getByRrn(CURRENT_EPC_CERTIFICATE_NUMBER)) - .thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - certificateNumber = CURRENT_EPC_CERTIFICATE_NUMBER, - latestCertificateNumberForThisProperty = CURRENT_EPC_CERTIFICATE_NUMBER, - expiryDate = validExpiryDate, - ), - ) - findYourEpcPage.submitCurrentEpcNumber() - val confirmEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByCertificateNumberPagePropertyRegistration::class) - - // Check Matched EPC - render page - assertThat(confirmEpcDetailsPage.sectionHeader).containsText(epcSectionHeader) - val expectedExpiryDate = - validExpiryDate - .toJavaLocalDate() - .format(DateTimeFormatter.ofPattern("d MMMM yyyy")) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.addressRow.value).containsText(MockEpcData.defaultSingleLineAddress) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.energyEfficiencyRatingRow.value).containsText("C") - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.expiryDateRow.value).containsText(expectedExpiryDate) - assertThat( - confirmEpcDetailsPage.summaryCard.summaryList.certificateNumberRow.value, - ).containsText(CURRENT_EPC_CERTIFICATE_NUMBER) - confirmEpcDetailsPage.submitYes() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.sectionHeader).isHidden() - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPageAfterEpc.clickRentedOutTaskWithName("Tenancy details") - val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) - householdsPage.submitNumberOfHouseholds(2) - val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) - peoplePage.submitNumOfPeople(2) - val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) - rentIncludesBillsPage.submitIsIncluded() - val billsIncludedPage = assertPageIs(page, BillsIncludedFormPagePropertyRegistration::class) - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.selectSomethingElseCheckbox() - billsIncludedPage.fillCustomBills("Dog Grooming") - billsIncludedPage.form.submit() - val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) - furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) - val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) - rentFrequencyPage.selectRentFrequency(RentFrequency.OTHER) - rentFrequencyPage.fillCustomRentFrequency("Fortnightly") - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) - rentAmountPage.submitRentAmount("400") - val taskListPageAfterTenancyDetails = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPageAfterTenancyDetails.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - // Check answers - render page - assertThat(checkAnswersPage.heading).containsText("Check your answers for:") - assertThat(checkAnswersPage.sectionHeader).containsText("Submit your registration") - assertThat(checkAnswersPage.complianceCertificatesHeading).isVisible() - assertThat(checkAnswersPage.gasSafetyHeading).isVisible() - assertThat(checkAnswersPage.electricalSafetyHeading).isVisible() - assertThat(checkAnswersPage.epcHeading).isVisible() - // submit - checkAnswersPage.confirm() - val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) - - // Confirmation - render page - val propertyOwnershipCaptor = captor() - verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) - val expectedPropertyRegNum = - RegistrationNumberDataModel.fromRegistrationNumber( - propertyOwnershipCaptor.value.registrationNumber, - ) - assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) - assertTrue(propertyOwnershipCaptor.value.isOccupied) - assertFalse(confirmationPage.whatYouNeedToDoNextHeading.isVisible) - assertTrue(confirmationPage.surveyLink.locator.isVisible) - assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) - - // Check confirmation email - verify(confirmationEmailSender).sendEmail( - "alex.surname@example.com", - PropertyRegistrationConfirmationEmail( - expectedPropertyRegNum.toString(), - "1 Fictional Road, FA1 1AA", - absoluteLandlordUrl, - true, - listOf("email2@address.com"), - ), - ) - - // Go to dashboard - confirmationPage.goToDashboardLink.clickAndWait() - assertPageIs(page, LandlordDashboardPage::class) - } - - @Test - @Suppress("ktlint:standard:max-line-length") - fun `User can navigate the whole journey in the enabled flow (manual address, custom property type, no license, unoccupied, no joint landlords, no certificates)`( - page: Page, - ) { - // Start page (not a journey step, but it is how the user accesses the journey) - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - assertThat(registerPropertyStartPage.heading).containsText("Register a property") - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // Task list page (part of the journey to support redirects) - taskListPage.clickAboutYourPropertyTaskWithName("Property details") - val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - - // Address lookup - render page - assertThat(addressLookupPage.form.fieldsetHeading).containsText("What is the property address?") - assertThat(addressLookupPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) - // fill in and submit - addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AB", "2") - val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) - - // Select address - render page - assertThat(selectAddressPage.form.fieldsetHeading).containsText("Select your address") - assertThat(selectAddressPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) - // fill in and submit - selectAddressPage.selectAddressAndSubmit(MANUAL_ADDRESS_CHOSEN) - val manualAddressPage = assertPageIs(page, ManualAddressFormPagePropertyRegistration::class) - - // Manual address - render page - assertThat(manualAddressPage.form.fieldsetHeading).containsText("What is the property address?") - assertThat(manualAddressPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) - // fill in and submit - manualAddressPage.submitAddress(addressLineOne = "Test address line 1", townOrCity = "Testville", postcode = "EG1 2AB") - val selectLocalCouncilPage = assertPageIs(page, SelectLocalCouncilFormPagePropertyRegistration::class) - - // Select local council - render page - assertThat(selectLocalCouncilPage.form.fieldsetHeading).containsText("What local council area is your property in?") - assertThat(selectLocalCouncilPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) - // fill in and submit - selectLocalCouncilPage.submitLocalCouncil("BATH AND NORTH EAST SOMERSET COUNCIL", "BATH AND NORTH EAST SOMERSET COUNCIL") - val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) - - // Property type selection - render page - assertThat(propertyTypePage.form.fieldsetHeading).containsText("What type of property are you registering?") - assertThat(propertyTypePage.form.sectionHeader).containsText(propertyDetailsSectionHeader) - // fill in and submit - propertyTypePage.submitCustomPropertyType("End terrace house") - val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) - - // Number of bedrooms - render page - assertThat(bedroomsPage.header).containsText("How many bedrooms in your property?") - assertThat(bedroomsPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) - bedroomsPage.submitNumOfBedrooms(3) - val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) - - // Ownership type selection - render page - assertThat(ownershipTypePage.form.fieldsetHeading).containsText("Select the type of ownership you have for your property") - assertThat(ownershipTypePage.form.sectionHeader).containsText(ownershipSectionHeader) - // fill in and submit - ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) - val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - - // Has Joint Landlords - render page - assertThat(hasJointLandlordsPage.header).containsText("Invite joint landlords") - assertThat(hasJointLandlordsPage.sectionHeader).containsText(ownershipSectionHeader) - - // fill in and submit - hasJointLandlordsPage.submitHasNoJointLandlords() - val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - - // Occupancy - render page - assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") - assertThat(occupancyPage.form.sectionHeader).containsText(occupiedSectionHeader) - // fill in and submit - occupancyPage.submitIsVacant() - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - - // Licensing type - render page - assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") - assertThat(licensingTypePage.form.sectionHeader).containsText(licenseSectionHeader) - // fill in and submit - licensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) - val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - - // Has Gas Supply - render page - assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) - assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert - render page - assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) - assertThat(hasGasCertPage.heading).containsText("Do you have a gas safety certificate for this property?") - hasGasCertPage.submitHasNoCertificate() - val gasCertMissingPage = assertPageIs(page, GasCertMissingFormPagePropertyRegistration::class) - - // Gas Cert Missing - render page - assertThat(gasCertMissingPage.sectionHeader).containsText(gasSafetyHeader) - assertThat(gasCertMissingPage.heading).containsText("You must get a gas safety certificate before a tenant moves in") - assertThat(gasCertMissingPage.warning).isHidden() - assertThat(gasCertMissingPage.submitButton).containsText("Continue") - gasCertMissingPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasNoCert() - val electricalCertMissingPage = assertPageIs(page, ElectricalCertMissingFormPagePropertyRegistration::class) - - // Electrical Cert Missing - render page - assertThat(electricalCertMissingPage.sectionHeader).containsText(electricalSafetyHeader) - assertThat( - electricalCertMissingPage.heading, - ).containsText("You must get an electrical safety certificate before a tenant moves in") - assertThat(electricalCertMissingPage.warning).isHidden() - assertThat(electricalCertMissingPage.submitButton).containsText("Continue") - electricalCertMissingPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // We use a manual address, uprn will be null. - // The internal EpcLookupByUprnStep at the start of the EpcTask will not find an EPC - taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(epcSectionHeader) - hasEpcPage.submitHasNoEpc() - val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) - - // Is EPC required - render page - assertThat(isEpcRequiredPage.form.sectionHeader).containsText(epcSectionHeader) - assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") - isEpcRequiredPage.submitEpcRequired() - val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) - - // EPC Missing - render page - assertThat(epcMissingPage.sectionHeader).containsText(epcSectionHeader) - assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - assertThat(epcMissingPage.continueButton).containsText("Continue") - assertThat(epcMissingPage.warning).isHidden() - epcMissingPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - // Check answers - render page - assertThat(checkAnswersPage.heading).containsText("Check your answers for:") - assertThat(checkAnswersPage.sectionHeader).containsText("Submit your registration") - // submit - checkAnswersPage.confirm() - val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) - - // Confirmation - render page - val propertyOwnershipCaptor = captor() - verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) - val expectedPropertyRegNum = - RegistrationNumberDataModel.fromRegistrationNumber( - propertyOwnershipCaptor.value.registrationNumber, - ) - assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) - assertFalse(propertyOwnershipCaptor.value.isOccupied) - assertTrue(confirmationPage.whatYouNeedToDoNextHeading.isHidden) - assertTrue(confirmationPage.surveyLink.locator.isVisible) - assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) - - // Check confirmation email - verify(confirmationEmailSender).sendEmail( - "alex.surname@example.com", - PropertyRegistrationConfirmationEmail( - expectedPropertyRegNum.toString(), - "Test address line 1, Testville, EG1 2AB", - absoluteLandlordUrl, - false, - null, + @Test + @Suppress("ktlint:standard:max-line-length") + fun `User can navigate the whole journey if pages are correctly filled in (select address, non-custom property type, selective license, occupied, compliance certificates uploaded)`( + page: Page, + ) { + // Start page (not a journey step, but it is how the user accesses the journey) + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + assertThat(registerPropertyStartPage.heading).containsText("Register a property") + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // Task list page (part of the journey to support redirects) + taskListPage.clickRegisterTaskWithName("Property address") + val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + + // Address lookup - render page + assertThat(addressLookupPage.form.fieldsetHeading).containsText("What is the property address?") + assertThat(addressLookupPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") + val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) + + // Select address - render page + assertThat(selectAddressPage.form.fieldsetHeading).containsText("Select your address") + assertThat(selectAddressPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") + val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) + + // Verify incomplete property is created at this point + verify(landlordIncompletePropertiesRepository).save(any()) + + // Property type selection - render page + assertThat(propertyTypePage.form.fieldsetHeading).containsText("What type of property are you registering?") + assertThat(propertyTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) + val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + + // Ownership type selection - render page + assertThat(ownershipTypePage.form.fieldsetHeading).containsText("Select the type of ownership you have for your property") + assertThat(ownershipTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + + // Licensing type - render page + assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") + assertThat(licensingTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + licensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) + val selectiveLicencePage = assertPageIs(page, SelectiveLicenceFormPagePropertyRegistration::class) + + // Selective licence - render page + assertThat(selectiveLicencePage.form.fieldsetHeading).containsText("What is your selective licence number?") + assertThat(selectiveLicencePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + selectiveLicencePage.submitLicenseNumber("licence number") + val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + + // Occupancy - render page + assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") + assertThat(occupancyPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + occupancyPage.submitIsOccupied() + val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) + + // Number of households - render page + assertThat(householdsPage.header).containsText("Households in your property") + assertThat(householdsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + householdsPage.submitNumberOfHouseholds(2) + val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) + + // Number of people - render page + assertThat(peoplePage.header).containsText("How many people live in your property?") + assertThat(peoplePage.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + peoplePage.submitNumOfPeople(2) + val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) + + // Number of bedrooms - render page + assertThat(bedroomsPage.header).containsText("How many bedrooms in your property?") + assertThat(bedroomsPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + bedroomsPage.submitNumOfBedrooms(3) + val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) + + // Does the rent include bills - render page + assertThat(rentIncludesBillsPage.form.fieldsetHeading).containsText("Does the rent include bills?") + assertThat(rentIncludesBillsPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + rentIncludesBillsPage.submitIsIncluded() + val billsIncludedPage = assertPageIs(page, BillsIncludedFormPagePropertyRegistration::class) + + // Bills included - render page + assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Which of these do you include in the rent?") + assertThat(billsIncludedPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.selectSomethingElseCheckbox() + billsIncludedPage.fillCustomBills("Dog Grooming") + billsIncludedPage.form.submit() + val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) + + // Furnished - render page + assertThat(furnishedPage.form.fieldsetHeading).containsText("Is the property furnished?") + assertThat(furnishedPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) + val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) + + // Rent frequency - render page + assertThat(rentFrequencyPage.header).containsText("When you charge rent") + assertThat(rentFrequencyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + rentFrequencyPage.selectRentFrequency(RentFrequency.OTHER) + rentFrequencyPage.fillCustomRentFrequency("Fortnightly") + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) + + // Rent amount - render page + assertThat(rentAmountPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + rentAmountPage.submitRentAmount("400") + val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + + // Has Joint Landlords - render page + assertThat(hasJointLandlordsPage.header).containsText("Invite joint landlords") + assertThat(hasJointLandlordsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + + // fill in and submit + hasJointLandlordsPage.submitHasJointLandlords() + val inviteJointLandlordPage = assertPageIs(page, InviteJointLandlordFormPagePropertyRegistration::class) + + // Invite joint landlord - render page + assertThat(inviteJointLandlordPage.heading).containsText("Invite a joint landlord to this property") + assertThat(inviteJointLandlordPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + + // fill in and submit + inviteJointLandlordPage.submitEmail("email@address.com") + var checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(checkJointLandlordsPage.summaryList.firstRow.value).containsText("email@address.com") + + // Check joint landlords - render page + checkJointLandlordsPage + .form + .addAnotherButton + .clickAndWait() + + // Invite another joint landlord - render page + val addAnotherPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + assertThat(addAnotherPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + addAnotherPage.submitEmail("email2@address.com") + + checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordsPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + + // Remove Joint Landlord - render page + val removeJointLandlordsPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordsPage.submitWantsToProceed() + + checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordsPage.form.submit() + + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + + // Has Gas Supply - render page + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert - render page + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasGasCertPage.heading).containsText("Do you have a gas safety certificate for this property?") + hasGasCertPage.submitHasCertificate() + val gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page + assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") + gasCertIssueDatePage.submitDate(validGasSafetyCertIssueDate) + var uploadGasCertPage = assertPageIs(page, UploadGasCertFormPagePropertyRegistration::class) + + // Upload Gas Cert - render page + assertThat(uploadGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + uploadGasCertPage.uploadGasCertificate(Path.of("src/test/resources/test-files/blank.png")) + var checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) + + // Check Gas Cert Uploads - render page + assertThat(checkGasCertUploadsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(checkGasCertUploadsPage.heading).containsText("You’ve uploaded 1 file") + assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + assertEquals(checkGasCertUploadsPage.table.rows.count(), 1) + checkGasCertUploadsPage.form.addAnotherButton.clickAndWait() + uploadGasCertPage = assertPageIs(page, UploadGasCertFormPagePropertyRegistration::class) + + uploadGasCertPage.uploadGasCertificate(Path.of("src/test/resources/test-files/blank.png")) + checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) + + assertThat(checkGasCertUploadsPage.heading).containsText("You’ve uploaded 2 files") + assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + assertThat(checkGasCertUploadsPage.table.getCell(1, 0)).containsText("blank.png") + assertEquals(checkGasCertUploadsPage.table.rows.count(), 2) + + checkGasCertUploadsPage.table + .getClickableCell(0, 2) + .link + .clickAndWait() + + val removeGasCertUploadPage = assertPageIs(page, RemoveGasCertUploadFormPagePropertyRegistration::class) + + removeGasCertUploadPage.form.radios.selectValue("true") + removeGasCertUploadPage.form.submit() + + checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) + assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + + assertEquals(checkGasCertUploadsPage.table.rows.count(), 1) + checkGasCertUploadsPage.form.submit() + + // Remove Gas Cert Upload - render page + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasEic() + val electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date - render page + assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(electricalCertExpiryDatePage.heading).containsText("What’s the expiry date on the Electrical Installation Certificate?") + electricalCertExpiryDatePage.submitDate(validExpiryDate) + var uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) + + // Upload Electrical Cert - render page + assertThat(uploadElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) + var checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + + // Check Electrical Cert Uploads - render page + assertThat(checkElectricalCertUploadsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 1) + checkElectricalCertUploadsPage.form.addAnotherButton.clickAndWait() + uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) + + uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) + checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + assertThat(checkElectricalCertUploadsPage.table.getCell(1, 0)).containsText("blank.png") + assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 2) + + checkElectricalCertUploadsPage.table + .getClickableCell(0, 2) + .link + .clickAndWait() + + val removeElectricalCertUploadPage = assertPageIs(page, RemoveElectricalCertUploadFormPagePropertyRegistration::class) + + removeElectricalCertUploadPage.form.radios.selectValue("true") + removeElectricalCertUploadPage.form.submit() + + checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + + assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 1) + checkElectricalCertUploadsPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep being able to find an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)) + .thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + expiryDate = validExpiryDate, ), ) - // Go to dashboard - confirmationPage.goToDashboardLink.clickAndWait() - assertPageIs(page, LandlordDashboardPage::class) - } - - @Test - fun `User can choose to provide compliance certificates later if their property is occupied`(page: Page) { - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) - assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert. Submit with no option selected - assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) - hasGasCertPage.submitProvideThisLater() - val provideGasCertLaterPage = assertPageIs(page, ProvideGasCertLaterFormPagePropertyRegistration::class) - - // Provide Gas Cert Later - render page - assertThat(provideGasCertLaterPage.sectionHeader).containsText(gasSafetyHeader) - assertThat(provideGasCertLaterPage.insetText).containsText("You must upload your gas safety certificate within 28 days") - provideGasCertLaterPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) - hasElectricalCertPage.submitProvideThisLater() - val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) - - // Provide Electrical Cert Later - render page - assertThat(provideElectricalCertLaterPage.sectionHeader).containsText(electricalSafetyHeader) - assertThat( - provideElectricalCertLaterPage.insetText, - ).containsText("You must upload your electrical safety certificate within 28 days.") - provideElectricalCertLaterPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC - taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(epcSectionHeader) - hasEpcPage.submitProvideThisLater() - val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) - - // Provide EPC Later - render page - assertThat(provideEpcLaterPage.sectionHeader).containsText(epcSectionHeader) - assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") - assertThat(provideEpcLaterPage.insetText).containsText( - "To keep the property registered, we need all its compliance certificates within 28 days.", - ) - provideEpcLaterPage.form.submit() - - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - assertPageIs(page, TaskListPagePropertyRegistration::class) - } - - @Test - fun `User can choose to provide compliance certificates later if their property is unoccupied`(page: Page) { - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = false) - assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert. Submit with no option selected - assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) - hasGasCertPage.submitProvideThisLater() - val provideGasCertLaterPage = assertPageIs(page, ProvideGasCertLaterFormPagePropertyRegistration::class) - - // Provide Gas Cert Later - render page - assertThat(provideGasCertLaterPage.sectionHeader).containsText(gasSafetyHeader) - assertThat(provideGasCertLaterPage.insetText).isHidden() - assertTrue( - provideGasCertLaterPage.page - .content() - .contains("You must get a gas safety certificate before a tenant moves in."), - ) - provideGasCertLaterPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) - hasElectricalCertPage.submitProvideThisLater() - val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) - - // Provide Electrical Cert Later - render page (unoccupied variant) - assertThat(provideElectricalCertLaterPage.sectionHeader).containsText(electricalSafetyHeader) - assertThat(provideElectricalCertLaterPage.heading).containsText("Provide your electrical safety certificate later") - assertThat(provideElectricalCertLaterPage.insetText).isHidden() - assertTrue( - provideElectricalCertLaterPage.page - .content() - .contains("You must get an electrical safety certificate before a tenant moves in."), - ) - provideElectricalCertLaterPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC - taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(epcSectionHeader) - hasEpcPage.submitProvideThisLater() - val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) - - // Provide EPC Later - render page - assertThat(provideEpcLaterPage.sectionHeader).containsText(epcSectionHeader) - assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") - assertThat(provideEpcLaterPage.insetText).isHidden() - provideEpcLaterPage.form.submit() - - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - assertPageIs(page, TaskListPagePropertyRegistration::class) - } - - @Test - fun `User can complete the journey with missing compliance certificates for an occupied property`(page: Page) { - // Gas supply page - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) - assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert page - assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) - hasGasCertPage.submitHasNoCertificate() - val gasCertMissingPage = assertPageIs(page, GasCertMissingFormPagePropertyRegistration::class) - - // Gas Cert Missing - render page - assertThat(gasCertMissingPage.sectionHeader).containsText(gasSafetyHeader) - assertThat(gasCertMissingPage.heading).containsText("You must get a valid gas safety certificate for this property") - assertThat(gasCertMissingPage.submitButton).containsText("Continue without a valid gas safety certificate") - assertThat(gasCertMissingPage.warning) - .containsText("You could face prosecution if you have tenants in a property without a gas safety certificate") - gasCertMissingPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasNoCert() - val electricalCertMissingPage = assertPageIs(page, ElectricalCertMissingFormPagePropertyRegistration::class) - - assertThat(electricalCertMissingPage.sectionHeader).containsText(electricalSafetyHeader) - assertThat( - electricalCertMissingPage.heading, - ).containsText("You must get a valid electrical safety certificate for this property") - assertThat(electricalCertMissingPage.warning) - .containsText("You could face prosecution if you have tenants in a property without an electrical safety certificate.") - assertThat(electricalCertMissingPage.submitButton).containsText("Continue without a valid electrical safety certificate") - electricalCertMissingPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC - taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(epcSectionHeader) - hasEpcPage.submitHasNoEpc() - val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) - - // Is EPC required - render page - assertThat(isEpcRequiredPage.form.sectionHeader).containsText(epcSectionHeader) - assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") - isEpcRequiredPage.submitEpcRequired() - val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) - - // EPC Missing - render page - assertThat(epcMissingPage.sectionHeader).containsText(epcSectionHeader) - assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - assertThat(epcMissingPage.continueAnywayButton).containsText("Continue anyway") - assertThat( - epcMissingPage.warning, - ).containsText("You can be fined for letting a property that does not meet energy efficiency requirements.") - epcMissingPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - assertThat(checkAnswersPage.sectionHeader).containsText("Submit your registration") - - // Check Answers - submit to reach Confirm Missing Compliance page - checkAnswersPage.form.submit() - val confirmMissingCompliancePage = assertPageIs(page, ConfirmMissingComplianceFormPagePropertyRegistration::class) - - // Confirm Missing Compliance - render page - assertThat(confirmMissingCompliancePage.heading).containsText("Confirm missing compliance certificates") - assertThat(confirmMissingCompliancePage.warning).isVisible() - assertThat(confirmMissingCompliancePage.form.sectionHeader).containsText("Submit registration") - - // Confirm Missing Compliance - submit - confirmMissingCompliancePage.form.radios.selectValue("true") - confirmMissingCompliancePage.form.submit() - val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) - - // Confirmation - verify record saved - val propertyOwnershipCaptor = captor() - verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) - val expectedPropertyRegNum = - RegistrationNumberDataModel.fromRegistrationNumber( - propertyOwnershipCaptor.value.registrationNumber, - ) - assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) - assertTrue(confirmationPage.surveyLink.locator.isVisible) - assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) - } - - @Test - fun `User can complete the journey with expired compliance certificates for an occupied property (epc found by uprn)`(page: Page) { - // Gas supply page - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) - assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert page - assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) - hasGasCertPage.submitHasCertificate() - var gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page - assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(gasSafetyHeader) - assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") - gasCertIssueDatePage.submitDate(expiredGasSafetyCertIssueDate) - var gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) - - // Gas Cert Expired - render page then navigate to edit issue date - assertThat(gasCertExpiredPage.sectionHeader).containsText(gasSafetyHeader) - assertThat(gasCertExpiredPage.mainHeading).containsText("This gas safety certificate has expired") - assertThat(gasCertExpiredPage.sectionHeading).containsText("You must get a valid gas safety certificate for this property") - assertThat(gasCertExpiredPage.warning) - .containsText("You could face prosecution if you have tenants in a property without a gas safety certificate.") - assertThat(gasCertExpiredPage.submitButton).containsText("Continue without a valid gas safety certificate") - gasCertExpiredPage.changeIssueDateLink.clickAndWait() - gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page, prepopulated with previous value, then submit again - assertThat(gasCertIssueDatePage.form.dayInput).hasValue(expiredGasSafetyCertIssueDate.dayOfMonth.toString()) - assertThat(gasCertIssueDatePage.form.monthInput).hasValue(expiredGasSafetyCertIssueDate.monthNumber.toString()) - assertThat(gasCertIssueDatePage.form.yearInput).hasValue(expiredGasSafetyCertIssueDate.year.toString()) - gasCertIssueDatePage.form.submit() - gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) - - // Back on Gas Cert Expired page - submit - gasCertExpiredPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasEic() - var electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date - render page - assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(electricalSafetyHeader) - electricalCertExpiryDatePage.submitDate(expiredExpiryDate) - var electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) - - // Electrical Cert Expired - render page then check change expiry date link - assertThat(electricalCertExpiredPage.sectionHeader).containsText(electricalSafetyHeader) - assertThat(electricalCertExpiredPage.warning) - .containsText("You could face prosecution if you have tenants in a property without an electrical safety certificate.") - assertThat(electricalCertExpiredPage.submitButton).containsText("Continue without a valid electrical safety certificate") - electricalCertExpiredPage.changeExpiryDateLink.clickAndWait() - electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date again - render page, prepopulated with previous value, then submit again - assertThat(electricalCertExpiryDatePage.form.dayInput).hasValue(expiredExpiryDate.dayOfMonth.toString()) - assertThat(electricalCertExpiryDatePage.form.monthInput).hasValue(expiredExpiryDate.monthNumber.toString()) - assertThat(electricalCertExpiryDatePage.form.yearInput).hasValue(expiredExpiryDate.year.toString()) - electricalCertExpiryDatePage.form.submit() - electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) - - // Back on Electrical Cert Expired page - submit - electricalCertExpiredPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep being able to find an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)) - .thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - expiryDate = expiredExpiryDate, - ), - ) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // EpcLookupByUprnStep finds the EPC, so redirects to Check UPRN matched EPCe - taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") - val confirmUprnMatchedEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) - - // Check UPRN matched EPC - submit Yes (accept this expired EPC, which triggers age/rating check internally) - assertThat(confirmUprnMatchedEpcDetailsPage.sectionHeader).containsText(epcSectionHeader) - confirmUprnMatchedEpcDetailsPage.submitYes() - val epcExpiryCheckPage = assertPageIs(page, EpcInDateAtStartOfTenancyCheckPagePropertyRegistration::class) - - assertThat(epcExpiryCheckPage.form.sectionHeader).containsText(epcSectionHeader) - epcExpiryCheckPage.submitEpcExpired() - val epcExpiredPage = assertPageIs(page, EpcExpiredFormPagePropertyRegistration::class) - - // EPC Expired - occupied variant: warning visible, "Continue anyway" button - assertThat(epcExpiredPage.sectionHeader).containsText(epcSectionHeader) - assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") - assertThat(epcExpiredPage.warning).isVisible() - assertThat(epcExpiredPage.submitButton).containsText("Continue anyway") - epcExpiredPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - assertThat(checkAnswersPage.sectionHeader).containsText("Submit your registration") - } - - @Test - fun `User can complete the journey with expired compliance certificates for an unoccupied property (epc not found by uprn)`( - page: Page, - ) { - // Gas supply page - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = false) - assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert page - assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) - hasGasCertPage.submitHasCertificate() - var gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page - assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(gasSafetyHeader) - assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") - gasCertIssueDatePage.submitDate(expiredGasSafetyCertIssueDate) - var gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) - - // Gas Cert Expired - render page then navigate to edit issue date - assertThat(gasCertExpiredPage.sectionHeader).containsText(gasSafetyHeader) - assertThat(gasCertExpiredPage.mainHeading).containsText("This gas safety certificate has expired") - assertThat(gasCertExpiredPage.sectionHeading).containsText("What to do next") - assertThat(gasCertExpiredPage.warning).isHidden() - assertThat(gasCertExpiredPage.submitButton).containsText("Save and continue") - gasCertExpiredPage.changeIssueDateLink.clickAndWait() - gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page, prepopulated with previous value, then submit again - assertThat(gasCertIssueDatePage.form.dayInput).hasValue(expiredGasSafetyCertIssueDate.dayOfMonth.toString()) - assertThat(gasCertIssueDatePage.form.monthInput).hasValue(expiredGasSafetyCertIssueDate.monthNumber.toString()) - assertThat(gasCertIssueDatePage.form.yearInput).hasValue(expiredGasSafetyCertIssueDate.year.toString()) - gasCertIssueDatePage.form.submit() - gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) - - // Back on Gas Cert Expired page - submit - gasCertExpiredPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasEic() - var electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date - render page - assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(electricalSafetyHeader) - electricalCertExpiryDatePage.submitDate(expiredExpiryDate) - var electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) - - // Electrical Cert Expired - render page then check change expiry date link - assertThat(electricalCertExpiredPage.sectionHeader).containsText(electricalSafetyHeader) - assertThat(electricalCertExpiredPage.warning).isHidden() - assertThat(electricalCertExpiredPage.submitButton).containsText("Save and continue") - electricalCertExpiredPage.changeExpiryDateLink.clickAndWait() - electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date again - render page, prepopulated with previous value, then submit again - assertThat(electricalCertExpiryDatePage.form.dayInput).hasValue(expiredExpiryDate.dayOfMonth.toString()) - assertThat(electricalCertExpiryDatePage.form.monthInput).hasValue(expiredExpiryDate.monthNumber.toString()) - assertThat(electricalCertExpiryDatePage.form.yearInput).hasValue(expiredExpiryDate.year.toString()) - electricalCertExpiryDatePage.form.submit() - electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) - - // Back on Electrical Cert Expired page - submit - electricalCertExpiredPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC - taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(epcSectionHeader) - hasEpcPage.submitHasEpc() - val findYourEpcPage = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) - - // EPC Search - render page - assertThat(findYourEpcPage.form.sectionHeader).containsText(epcSectionHeader) - whenever(epcRegisterClient.getByRrn(CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER)) - .thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - certificateNumber = CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER, - expiryDate = expiredExpiryDate, - latestCertificateNumberForThisProperty = CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER, - ), - ) - findYourEpcPage.submitCurrentEpcNumberWhichIsExpired() - val confirmEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByCertificateNumberPagePropertyRegistration::class) - - // Check Matched EPC - render page - assertThat(confirmEpcDetailsPage.sectionHeader).containsText(epcSectionHeader) - val expectedExpiryDate = - expiredExpiryDate - .toJavaLocalDate() - .format(DateTimeFormatter.ofPattern("d MMMM yyyy")) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.addressRow.value).containsText(MockEpcData.defaultSingleLineAddress) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.energyEfficiencyRatingRow.value).containsText("C") - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.expiryDateRow.value).containsText(expectedExpiryDate) - assertThat( - confirmEpcDetailsPage.summaryCard.summaryList.certificateNumberRow.value, - ).containsText(CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER) - confirmEpcDetailsPage.submitYes() - val epcExpiredPage = assertPageIs(page, EpcExpiredFormPagePropertyRegistration::class) - - // EPC Expired - unoccupied variant: no warning, "Continue" button - assertThat(epcExpiredPage.sectionHeader).containsText(epcSectionHeader) - assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") - assertThat(epcExpiredPage.warning).isHidden() - assertThat(epcExpiredPage.submitButton).containsText("Continue") - epcExpiredPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - assertThat(checkAnswersPage.sectionHeader).containsText("Submit your registration") - } - - @Test - fun `The Electrical Safety task can be completed by the user uploaded an eicr`(page: Page) { - // Skip to Has Electrical Cert page and submit "Yes" - val hasElectricalCertPage = navigator.skipToPropertyRegistrationHasElectricalCertPage() - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) - hasElectricalCertPage.submitHasEicr() - val electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date - render page - assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(electricalSafetyHeader) - assertThat( - electricalCertExpiryDatePage.heading, - ).containsText("What’s the expiry date on the Electrical Installation Condition Report?") - electricalCertExpiryDatePage.submitDate(validExpiryDate) - val uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) - - // Upload Electrical Cert - render page - assertThat(uploadElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) - assertThat(uploadElectricalCertPage.heading).containsText("Upload the Electrical Installation Condition Report (EICR)") - uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) - - // Check Electrical Safety Answers - EICR variant verified by heading text - } - - @Test - fun `The EPC task can be completed when FindYourEpc finds a superseded epc`(page: Page) { - // Skip to Find Your EPC page and submit "Superseded EPC Found" - val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() - assertThat(findYourEpcPage.form.sectionHeader).containsText(epcSectionHeader) - whenever(epcRegisterClient.getByRrn(SUPERSEDED_EPC_CERTIFICATE_NUMBER)).thenReturn( + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // EpcLookupByUprnStep finds the EPC, so redirects to Check UPRN matched EPC + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val confirmUprnMatchedEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) + + // Confirm UPRN matched EPC - submit No (don't use this EPC) + assertThat(confirmUprnMatchedEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + confirmUprnMatchedEpcDetailsPage.submitNo() + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasEpcPage.submitHasEpc() + val findYourEpcPage = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) + + // EPC Search - render page + assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + whenever(epcRegisterClient.getByRrn(CURRENT_EPC_CERTIFICATE_NUMBER)) + .thenReturn( MockEpcData.createEpcRegisterClientEpcFoundResponse( - certificateNumber = SUPERSEDED_EPC_CERTIFICATE_NUMBER, - expiryDate = MockEpcData.expiryDateInThePast, + certificateNumber = CURRENT_EPC_CERTIFICATE_NUMBER, latestCertificateNumberForThisProperty = CURRENT_EPC_CERTIFICATE_NUMBER, + expiryDate = validExpiryDate, ), ) - whenever(epcRegisterClient.getByRrn(CURRENT_EPC_CERTIFICATE_NUMBER)).thenReturn( + findYourEpcPage.submitCurrentEpcNumber() + val confirmEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByCertificateNumberPagePropertyRegistration::class) + + // Check Matched EPC - render page + assertThat(confirmEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + val expectedExpiryDate = + validExpiryDate + .toJavaLocalDate() + .format(DateTimeFormatter.ofPattern("d MMMM yyyy")) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.addressRow.value).containsText(MockEpcData.defaultSingleLineAddress) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.energyEfficiencyRatingRow.value).containsText("C") + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.expiryDateRow.value).containsText(expectedExpiryDate) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.certificateNumberRow.value).containsText(CURRENT_EPC_CERTIFICATE_NUMBER) + confirmEpcDetailsPage.submitYes() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + // Check answers - render page + assertThat(checkAnswersPage.heading).containsText("Check your answers for:") + assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") + assertThat(checkAnswersPage.complianceCertificatesHeading).isVisible() + assertThat(checkAnswersPage.gasSafetyHeading).isVisible() + assertThat(checkAnswersPage.electricalSafetyHeading).isVisible() + assertThat(checkAnswersPage.epcHeading).isVisible() + // submit + checkAnswersPage.confirm() + val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) + + // Confirmation - render page + val propertyOwnershipCaptor = captor() + verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) + val expectedPropertyRegNum = RegistrationNumberDataModel.fromRegistrationNumber(propertyOwnershipCaptor.value.registrationNumber) + assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) + assertTrue(propertyOwnershipCaptor.value.isOccupied) + assertFalse(confirmationPage.whatYouNeedToDoNextHeading.isVisible) + assertTrue(confirmationPage.surveyLink.locator.isVisible) + assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) + + // Check confirmation email + verify(confirmationEmailSender).sendEmail( + "alex.surname@example.com", + PropertyRegistrationConfirmationEmail( + expectedPropertyRegNum.toString(), + "1 Fictional Road, FA1 1AA", + absoluteLandlordUrl, + true, + listOf("email2@address.com"), + ), + ) + + // Go to dashboard + confirmationPage.goToDashboardLink.clickAndWait() + assertPageIs(page, LandlordDashboardPage::class) + } + + @Test + @Suppress("ktlint:standard:max-line-length") + fun `User can navigate the whole journey if pages are correctly filled in (manual address, custom property type, no license, unoccupied, no joint landlords, no certificates)`( + page: Page, + ) { + // Start page (not a journey step, but it is how the user accesses the journey) + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + assertThat(registerPropertyStartPage.heading).containsText("Register a property") + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // Task list page (part of the journey to support redirects) + taskListPage.clickRegisterTaskWithName("Property address") + val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + + // Address lookup - render page + assertThat(addressLookupPage.form.fieldsetHeading).containsText("What is the property address?") + assertThat(addressLookupPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AB", "2") + val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) + + // Select address - render page + assertThat(selectAddressPage.form.fieldsetHeading).containsText("Select your address") + assertThat(selectAddressPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + selectAddressPage.selectAddressAndSubmit(MANUAL_ADDRESS_CHOSEN) + val manualAddressPage = assertPageIs(page, ManualAddressFormPagePropertyRegistration::class) + + // Manual address - render page + assertThat(manualAddressPage.form.fieldsetHeading).containsText("What is the property address?") + assertThat(manualAddressPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + manualAddressPage.submitAddress(addressLineOne = "Test address line 1", townOrCity = "Testville", postcode = "EG1 2AB") + val selectLocalCouncilPage = assertPageIs(page, SelectLocalCouncilFormPagePropertyRegistration::class) + + // Select local council - render page + assertThat(selectLocalCouncilPage.form.fieldsetHeading).containsText("What local council area is your property in?") + assertThat(selectLocalCouncilPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + selectLocalCouncilPage.submitLocalCouncil("BATH AND NORTH EAST SOMERSET COUNCIL", "BATH AND NORTH EAST SOMERSET COUNCIL") + val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) + + // Property type selection - render page + assertThat(propertyTypePage.form.fieldsetHeading).containsText("What type of property are you registering?") + assertThat(propertyTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + propertyTypePage.submitCustomPropertyType("End terrace house") + val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + + // Ownership type selection - render page + assertThat(ownershipTypePage.form.fieldsetHeading).containsText("Select the type of ownership you have for your property") + assertThat(ownershipTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + + // Licensing type - render page + assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") + assertThat(licensingTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + licensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) + val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + + // Occupancy - render page + assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") + assertThat(occupancyPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + occupancyPage.submitIsVacant() + val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + + // Has Joint Landlords - render page + assertThat(hasJointLandlordsPage.header).containsText("Invite joint landlords") + assertThat(hasJointLandlordsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + + // fill in and submit + hasJointLandlordsPage.submitHasNoJointLandlords() + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + + // Has Gas Supply - render page + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert - render page + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasGasCertPage.heading).containsText("Do you have a gas safety certificate for this property?") + hasGasCertPage.submitHasNoCertificate() + val gasCertMissingPage = assertPageIs(page, GasCertMissingFormPagePropertyRegistration::class) + + // Gas Cert Missing - render page + assertThat(gasCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertMissingPage.heading).containsText("You must get a gas safety certificate before a tenant moves in") + assertThat(gasCertMissingPage.warning).isHidden() + assertThat(gasCertMissingPage.submitButton).containsText("Continue") + gasCertMissingPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasNoCert() + val electricalCertMissingPage = assertPageIs(page, ElectricalCertMissingFormPagePropertyRegistration::class) + + // Electrical Cert Missing - render page + assertThat(electricalCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(electricalCertMissingPage.heading).containsText("You must get an electrical safety certificate before a tenant moves in") + assertThat(electricalCertMissingPage.warning).isHidden() + assertThat(electricalCertMissingPage.submitButton).containsText("Continue") + electricalCertMissingPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // We use a manual address, uprn will be null. + // The internal EpcLookupByUprnStep at the start of the EpcTask will not find an EPC + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasEpcPage.submitHasNoEpc() + val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) + + // Is EPC required - render page + assertThat(isEpcRequiredPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") + isEpcRequiredPage.submitEpcRequired() + val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) + + // EPC Missing - render page + assertThat(epcMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + assertThat(epcMissingPage.continueButton).containsText("Continue") + assertThat(epcMissingPage.warning).isHidden() + epcMissingPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + // Check answers - render page + assertThat(checkAnswersPage.heading).containsText("Check your answers for:") + assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") + // submit + checkAnswersPage.confirm() + val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) + + // Confirmation - render page + val propertyOwnershipCaptor = captor() + verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) + val expectedPropertyRegNum = RegistrationNumberDataModel.fromRegistrationNumber(propertyOwnershipCaptor.value.registrationNumber) + assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) + assertFalse(propertyOwnershipCaptor.value.isOccupied) + assertTrue(confirmationPage.whatYouNeedToDoNextHeading.isHidden) + assertTrue(confirmationPage.surveyLink.locator.isVisible) + assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) + + // Check confirmation email + verify(confirmationEmailSender).sendEmail( + "alex.surname@example.com", + PropertyRegistrationConfirmationEmail( + expectedPropertyRegNum.toString(), + "Test address line 1, Testville, EG1 2AB", + absoluteLandlordUrl, + false, + null, + ), + ) + + // Go to dashboard + confirmationPage.goToDashboardLink.clickAndWait() + assertPageIs(page, LandlordDashboardPage::class) + } + + @Test + fun `User can choose to provide compliance certificates later if their property is occupied`(page: Page) { + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert. Submit with no option selected + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasCertPage.submitProvideThisLater() + val provideGasCertLaterPage = assertPageIs(page, ProvideGasCertLaterFormPagePropertyRegistration::class) + + // Provide Gas Cert Later - render page + assertThat(provideGasCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(provideGasCertLaterPage.insetText).containsText("You must upload your gas safety certificate within 28 days") + provideGasCertLaterPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasElectricalCertPage.submitProvideThisLater() + val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) + + // Provide Electrical Cert Later - render page + assertThat(provideElectricalCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat( + provideElectricalCertLaterPage.insetText, + ).containsText("You must upload your electrical safety certificate within 28 days.") + provideElectricalCertLaterPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasEpcPage.submitProvideThisLater() + val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) + + // Provide EPC Later - render page + assertThat(provideEpcLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") + assertThat(provideEpcLaterPage.insetText).containsText( + "To keep the property registered, we need all its compliance certificates within 28 days.", + ) + provideEpcLaterPage.form.submit() + + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + assertPageIs(page, TaskListPagePropertyRegistration::class) + } + + @Test + fun `User can choose to provide compliance certificates later if their property is unoccupied`(page: Page) { + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = false) + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert. Submit with no option selected + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasCertPage.submitProvideThisLater() + val provideGasCertLaterPage = assertPageIs(page, ProvideGasCertLaterFormPagePropertyRegistration::class) + + // Provide Gas Cert Later - render page + assertThat(provideGasCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(provideGasCertLaterPage.insetText).isHidden() + assertTrue( + provideGasCertLaterPage.page + .content() + .contains("You must get a gas safety certificate before a tenant moves in."), + ) + provideGasCertLaterPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasElectricalCertPage.submitProvideThisLater() + val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) + + // Provide Electrical Cert Later - render page (unoccupied variant) + assertThat(provideElectricalCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(provideElectricalCertLaterPage.heading).containsText("Provide your electrical safety certificate later") + assertThat(provideElectricalCertLaterPage.insetText).isHidden() + assertTrue( + provideElectricalCertLaterPage.page + .content() + .contains("You must get an electrical safety certificate before a tenant moves in."), + ) + provideElectricalCertLaterPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasEpcPage.submitProvideThisLater() + val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) + + // Provide EPC Later - render page + assertThat(provideEpcLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") + assertThat(provideEpcLaterPage.insetText).isHidden() + provideEpcLaterPage.form.submit() + + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + assertPageIs(page, TaskListPagePropertyRegistration::class) + } + + @Test + fun `User can complete the journey with missing compliance certificates for an occupied property`(page: Page) { + // Gas supply page + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert page + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasCertPage.submitHasNoCertificate() + val gasCertMissingPage = assertPageIs(page, GasCertMissingFormPagePropertyRegistration::class) + + // Gas Cert Missing - render page + assertThat(gasCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertMissingPage.heading).containsText("You must get a valid gas safety certificate for this property") + assertThat(gasCertMissingPage.submitButton).containsText("Continue without a valid gas safety certificate") + assertThat(gasCertMissingPage.warning) + .containsText("You could face prosecution if you have tenants in a property without a gas safety certificate") + gasCertMissingPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasNoCert() + val electricalCertMissingPage = assertPageIs(page, ElectricalCertMissingFormPagePropertyRegistration::class) + + assertThat(electricalCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(electricalCertMissingPage.heading).containsText("You must get a valid electrical safety certificate for this property") + assertThat(electricalCertMissingPage.warning) + .containsText("You could face prosecution if you have tenants in a property without an electrical safety certificate.") + assertThat(electricalCertMissingPage.submitButton).containsText("Continue without a valid electrical safety certificate") + electricalCertMissingPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasEpcPage.submitHasNoEpc() + val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) + + // Is EPC required - render page + assertThat(isEpcRequiredPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") + isEpcRequiredPage.submitEpcRequired() + val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) + + // EPC Missing - render page + assertThat(epcMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + assertThat(epcMissingPage.continueAnywayButton).containsText("Continue anyway") + assertThat( + epcMissingPage.warning, + ).containsText("You can be fined for letting a property that does not meet energy efficiency requirements.") + epcMissingPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") + + // Check Answers - submit to reach Confirm Missing Compliance page + checkAnswersPage.form.submit() + val confirmMissingCompliancePage = assertPageIs(page, ConfirmMissingComplianceFormPagePropertyRegistration::class) + + // Confirm Missing Compliance - render page + assertThat(confirmMissingCompliancePage.heading).containsText("Confirm missing compliance certificates") + assertThat(confirmMissingCompliancePage.warning).isVisible() + assertThat(confirmMissingCompliancePage.form.sectionHeader).containsText("Submit registration") + + // Confirm Missing Compliance - submit + confirmMissingCompliancePage.form.radios.selectValue("true") + confirmMissingCompliancePage.form.submit() + val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) + + // Confirmation - verify record saved + val propertyOwnershipCaptor = captor() + verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) + val expectedPropertyRegNum = RegistrationNumberDataModel.fromRegistrationNumber(propertyOwnershipCaptor.value.registrationNumber) + assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) + assertTrue(confirmationPage.surveyLink.locator.isVisible) + assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) + } + + @Test + fun `User can complete the journey with expired compliance certificates for an occupied property (epc found by uprn)`(page: Page) { + // Gas supply page + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert page + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasCertPage.submitHasCertificate() + var gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page + assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") + gasCertIssueDatePage.submitDate(expiredGasSafetyCertIssueDate) + var gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) + + // Gas Cert Expired - render page then navigate to edit issue date + assertThat(gasCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertExpiredPage.mainHeading).containsText("This gas safety certificate has expired") + assertThat(gasCertExpiredPage.sectionHeading).containsText("You must get a valid gas safety certificate for this property") + assertThat(gasCertExpiredPage.warning) + .containsText("You could face prosecution if you have tenants in a property without a gas safety certificate.") + assertThat(gasCertExpiredPage.submitButton).containsText("Continue without a valid gas safety certificate") + gasCertExpiredPage.changeIssueDateLink.clickAndWait() + gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page, prepopulated with previous value, then submit again + assertThat(gasCertIssueDatePage.form.dayInput).hasValue(expiredGasSafetyCertIssueDate.dayOfMonth.toString()) + assertThat(gasCertIssueDatePage.form.monthInput).hasValue(expiredGasSafetyCertIssueDate.monthNumber.toString()) + assertThat(gasCertIssueDatePage.form.yearInput).hasValue(expiredGasSafetyCertIssueDate.year.toString()) + gasCertIssueDatePage.form.submit() + gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) + + // Back on Gas Cert Expired page - submit + gasCertExpiredPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasEic() + var electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date - render page + assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + electricalCertExpiryDatePage.submitDate(expiredExpiryDate) + var electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) + + // Electrical Cert Expired - render page then check change expiry date link + assertThat(electricalCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(electricalCertExpiredPage.warning) + .containsText("You could face prosecution if you have tenants in a property without an electrical safety certificate.") + assertThat(electricalCertExpiredPage.submitButton).containsText("Continue without a valid electrical safety certificate") + electricalCertExpiredPage.changeExpiryDateLink.clickAndWait() + electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date again - render page, prepopulated with previous value, then submit again + assertThat(electricalCertExpiryDatePage.form.dayInput).hasValue(expiredExpiryDate.dayOfMonth.toString()) + assertThat(electricalCertExpiryDatePage.form.monthInput).hasValue(expiredExpiryDate.monthNumber.toString()) + assertThat(electricalCertExpiryDatePage.form.yearInput).hasValue(expiredExpiryDate.year.toString()) + electricalCertExpiryDatePage.form.submit() + electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) + + // Back on Electrical Cert Expired page - submit + electricalCertExpiredPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep being able to find an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)) + .thenReturn( MockEpcData.createEpcRegisterClientEpcFoundResponse( - certificateNumber = CURRENT_EPC_CERTIFICATE_NUMBER, + expiryDate = expiredExpiryDate, ), ) - findYourEpcPage.submitSupersededEpcNumber() - val epcSupersededPage = assertPageIs(page, EpcSuperseededFormPagePropertyRegistration::class) - - // Check details of superseded and latest epc - render page - assertThat(epcSupersededPage.sectionHeader).containsText(epcSectionHeader) - epcSupersededPage.submitContinueWithLatest() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - assertPageIs(page, TaskListPagePropertyRegistration::class) - } - - @Test - fun `The EPC task can be completed when FindYourEpc finds no epc and it is missing`(page: Page) { - // Skip to Find Your EPC page and submit "No EPC Found" - val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() - assertThat(findYourEpcPage.form.sectionHeader).containsText(epcSectionHeader) - whenever( - epcRegisterClient.getByRrn(NONEXISTENT_EPC_CERTIFICATE_NUMBER), - ).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - findYourEpcPage.submitNonexistentEpcNumber() - val epcNotFoundPage = assertPageIs(page, EpcNotFoundFormPagePropertyRegistration::class) - - // EPC not found - render page - assertThat(epcNotFoundPage.sectionHeader).containsText(epcSectionHeader) - assertThat(epcNotFoundPage.heading).containsText("We could not find your EPC") - assertThat(epcNotFoundPage.certificateNumberText).containsText(NONEXISTENT_EPC_CERTIFICATE_NUMBER) - assertThat(epcNotFoundPage.searchAgainLink).isVisible() - - // Click 'search again' to return to Find Your EPC and re-submit not found - epcNotFoundPage.searchAgainLink.click() - val findYourEpcPageAgain = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) - assertThat(findYourEpcPageAgain.form.sectionHeader).containsText(epcSectionHeader) - whenever( - epcRegisterClient.getByRrn(NONEXISTENT_EPC_CERTIFICATE_NUMBER), - ).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - findYourEpcPageAgain.submitNonexistentEpcNumber() - assertPageIs(page, EpcNotFoundFormPagePropertyRegistration::class).form.submit() - - val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) - - // Is EPC required - render page - assertThat(isEpcRequiredPage.form.sectionHeader).containsText(epcSectionHeader) - assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") - isEpcRequiredPage.submitEpcRequired() - val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) - - // EPC Missing - render page - assertThat(epcMissingPage.sectionHeader).containsText(epcSectionHeader) - assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - assertThat(epcMissingPage.continueAnywayButton).containsText("Continue anyway") - assertThat( - epcMissingPage.warning, - ).containsText("You can be fined for letting a property that does not meet energy efficiency requirements.") - epcMissingPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - assertPageIs(page, TaskListPagePropertyRegistration::class) - } - - @Test - fun `User can navigate the MEES flow when they have a MEES exemption`(page: Page) { - val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() - - // Has MEES Exemption - render page - assertThat(hasMeesExemptionPage.sectionHeader).containsText(epcSectionHeader) - assertThat(hasMeesExemptionPage.heading).containsText("You need a registered energy efficiency exemption to let this property") - hasMeesExemptionPage.submitHasMeesExemption() - val meesExemptionPage = assertPageIs(page, MeesExemptionFormPagePropertyRegistration::class) - - // MEES Exemption - select exemption reason - assertThat(meesExemptionPage.form.sectionHeader).containsText(epcSectionHeader) - meesExemptionPage.submitExemptionReason(MeesExemptionReason.HIGH_COST) - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - } - - @Test - fun `User can navigate the MEES flow when they do not have a MEES exemption`(page: Page) { - val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() - - // Has MEES Exemption - submit no exemption - assertThat(hasMeesExemptionPage.sectionHeader).containsText(epcSectionHeader) - hasMeesExemptionPage.submitHasNoMeesExemption() - val lowEnergyRatingPage = assertPageIs(page, LowEnergyRatingFormPagePropertyRegistration::class) - - // Low Energy Rating - render page - assertThat(lowEnergyRatingPage.sectionHeader).containsText(epcSectionHeader) - assertThat(lowEnergyRatingPage.heading).containsText("This property does not meet energy efficiency requirements for letting") - lowEnergyRatingPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - } - - @Test - fun `User can navigate the EPC exemption flow`(page: Page) { - val epcExemptionPage = navigator.skipToPropertyRegistrationEpcExemptionPage() - - // EPC Exemption - select exemption reason - assertThat(epcExemptionPage.form.sectionHeader).containsText(epcSectionHeader) - epcExemptionPage.submitExemptionReason(EpcExemptionReason.PROTECTED_ARCHITECTURAL_OR_HISTORICAL_MERIT) - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - } - - @Test - fun `task list back link navigates to start page after entering from start page`(page: Page) { - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPage.backLink.clickAndWait() - assertPageIs(page, RegisterPropertyStartPage::class) - } - - @Test - fun `task list back link navigates to start page after entering from start page and returning from a task`(page: Page) { - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPage.clickRegisterTaskWithName("Property details") - assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - - val backLink = BackLink.default(page) - backLink.clickAndWait() - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPage.backLink.clickAndWait() - assertPageIs(page, RegisterPropertyStartPage::class) - } - - @Test - fun `restructured task list shows three sections with expected task order`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - assertEquals(3, taskListPage.getSectionCount()) - assertThat(taskListPage.getSectionHeading(0)).hasText("About your property") - assertThat(taskListPage.getSectionHeading(1)).hasText("How your property’s rented out") - assertThat(taskListPage.getSectionHeading(2)).hasText("Submit your registration") - assertEquals( - listOf("Property details", "Ownership and landlords", "Tell us if your property’s occupied"), - taskListPage.getAboutYourPropertyTaskNames(), - ) - assertEquals( - listOf( - "Tell us if your property needs a license", - "Gas safety certificate", - "Electrical safety certificate", - "Energy performance certificate (EPC)", - "Tenancy details", + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // EpcLookupByUprnStep finds the EPC, so redirects to Check UPRN matched EPCe + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val confirmUprnMatchedEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) + + // Check UPRN matched EPC - submit Yes (accept this expired EPC, which triggers age/rating check internally) + assertThat(confirmUprnMatchedEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + confirmUprnMatchedEpcDetailsPage.submitYes() + val epcExpiryCheckPage = assertPageIs(page, EpcInDateAtStartOfTenancyCheckPagePropertyRegistration::class) + + assertThat(epcExpiryCheckPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + epcExpiryCheckPage.submitEpcExpired() + val epcExpiredPage = assertPageIs(page, EpcExpiredFormPagePropertyRegistration::class) + + // EPC Expired - occupied variant: warning visible, "Continue anyway" button + assertThat(epcExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") + assertThat(epcExpiredPage.warning).isVisible() + assertThat(epcExpiredPage.submitButton).containsText("Continue anyway") + epcExpiredPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") + } + + @Test + fun `User can complete the journey with expired compliance certificates for an unoccupied property (epc not found by uprn)`( + page: Page, + ) { + // Gas supply page + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = false) + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert page + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasCertPage.submitHasCertificate() + var gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page + assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") + gasCertIssueDatePage.submitDate(expiredGasSafetyCertIssueDate) + var gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) + + // Gas Cert Expired - render page then navigate to edit issue date + assertThat(gasCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertExpiredPage.mainHeading).containsText("This gas safety certificate has expired") + assertThat(gasCertExpiredPage.sectionHeading).containsText("What to do next") + assertThat(gasCertExpiredPage.warning).isHidden() + assertThat(gasCertExpiredPage.submitButton).containsText("Save and continue") + gasCertExpiredPage.changeIssueDateLink.clickAndWait() + gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page, prepopulated with previous value, then submit again + assertThat(gasCertIssueDatePage.form.dayInput).hasValue(expiredGasSafetyCertIssueDate.dayOfMonth.toString()) + assertThat(gasCertIssueDatePage.form.monthInput).hasValue(expiredGasSafetyCertIssueDate.monthNumber.toString()) + assertThat(gasCertIssueDatePage.form.yearInput).hasValue(expiredGasSafetyCertIssueDate.year.toString()) + gasCertIssueDatePage.form.submit() + gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) + + // Back on Gas Cert Expired page - submit + gasCertExpiredPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasEic() + var electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date - render page + assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + electricalCertExpiryDatePage.submitDate(expiredExpiryDate) + var electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) + + // Electrical Cert Expired - render page then check change expiry date link + assertThat(electricalCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(electricalCertExpiredPage.warning).isHidden() + assertThat(electricalCertExpiredPage.submitButton).containsText("Save and continue") + electricalCertExpiredPage.changeExpiryDateLink.clickAndWait() + electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date again - render page, prepopulated with previous value, then submit again + assertThat(electricalCertExpiryDatePage.form.dayInput).hasValue(expiredExpiryDate.dayOfMonth.toString()) + assertThat(electricalCertExpiryDatePage.form.monthInput).hasValue(expiredExpiryDate.monthNumber.toString()) + assertThat(electricalCertExpiryDatePage.form.yearInput).hasValue(expiredExpiryDate.year.toString()) + electricalCertExpiryDatePage.form.submit() + electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) + + // Back on Electrical Cert Expired page - submit + electricalCertExpiredPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasEpcPage.submitHasEpc() + val findYourEpcPage = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) + + // EPC Search - render page + assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + whenever(epcRegisterClient.getByRrn(CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER)) + .thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + certificateNumber = CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER, + expiryDate = expiredExpiryDate, + latestCertificateNumberForThisProperty = CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER, ), - taskListPage.getRentedOutTaskNames(), - ) - assertEquals( - listOf("Check and submit your answers"), - taskListPage.getSubmitYourRegistrationTaskNames(), ) + findYourEpcPage.submitCurrentEpcNumberWhichIsExpired() + val confirmEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByCertificateNumberPagePropertyRegistration::class) + + // Check Matched EPC - render page + assertThat(confirmEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + val expectedExpiryDate = + expiredExpiryDate + .toJavaLocalDate() + .format(DateTimeFormatter.ofPattern("d MMMM yyyy")) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.addressRow.value).containsText(MockEpcData.defaultSingleLineAddress) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.energyEfficiencyRatingRow.value).containsText("C") + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.expiryDateRow.value).containsText(expectedExpiryDate) + assertThat( + confirmEpcDetailsPage.summaryCard.summaryList.certificateNumberRow.value, + ).containsText(CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER) + confirmEpcDetailsPage.submitYes() + val epcExpiredPage = assertPageIs(page, EpcExpiredFormPagePropertyRegistration::class) + + // EPC Expired - unoccupied variant: no warning, "Continue" button + assertThat(epcExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") + assertThat(epcExpiredPage.warning).isHidden() + assertThat(epcExpiredPage.submitButton).containsText("Continue") + epcExpiredPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") + } - assertTrue(taskListPage.getAboutYourPropertyTask("Property details").hasLink) - taskListPage.clickAboutYourPropertyTaskWithName("Property details") - assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - } + @Test + fun `The Electrical Safety task can be completed by the user uploaded an eicr`(page: Page) { + // Skip to Has Electrical Cert page and submit "Yes" + val hasElectricalCertPage = navigator.skipToPropertyRegistrationHasElectricalCertPage() + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasElectricalCertPage.submitHasEicr() + val electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date - render page + assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat( + electricalCertExpiryDatePage.heading, + ).containsText("What’s the expiry date on the Electrical Installation Condition Report?") + electricalCertExpiryDatePage.submitDate(validExpiryDate) + val uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) + + // Upload Electrical Cert - render page + assertThat(uploadElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(uploadElectricalCertPage.heading).containsText("Upload the Electrical Installation Condition Report (EICR)") + uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) + + // Check Electrical Safety Answers - EICR variant verified by heading text + } - @Test - fun `restructured task list shows tenancy details as not required when the property is unoccupied`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + @Test + fun `The EPC task can be completed when FindYourEpc finds a superseded epc`(page: Page) { + // Skip to Find Your EPC page and submit "Superseded EPC Found" + val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() + assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + whenever(epcRegisterClient.getByRrn(SUPERSEDED_EPC_CERTIFICATE_NUMBER)).thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + certificateNumber = SUPERSEDED_EPC_CERTIFICATE_NUMBER, + expiryDate = MockEpcData.expiryDateInThePast, + latestCertificateNumberForThisProperty = CURRENT_EPC_CERTIFICATE_NUMBER, + ), + ) + whenever(epcRegisterClient.getByRrn(CURRENT_EPC_CERTIFICATE_NUMBER)).thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + certificateNumber = CURRENT_EPC_CERTIFICATE_NUMBER, + ), + ) + findYourEpcPage.submitSupersededEpcNumber() + val epcSupersededPage = assertPageIs(page, EpcSuperseededFormPagePropertyRegistration::class) + + // Check details of superseded and latest epc - render page + assertThat(epcSupersededPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + epcSupersededPage.submitContinueWithLatest() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + assertPageIs(page, TaskListPagePropertyRegistration::class) + } - val taskListPage = navigator.goToRestructuredPropertyRegistrationTaskListUnoccupied() - val tenancyDetailsTask = taskListPage.getRentedOutTask("Tenancy details") + @Test + fun `The EPC task can be completed when FindYourEpc finds no epc and it is missing`(page: Page) { + // Skip to Find Your EPC page and submit "No EPC Found" + val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() + assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + whenever( + epcRegisterClient.getByRrn(NONEXISTENT_EPC_CERTIFICATE_NUMBER), + ).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + findYourEpcPage.submitNonexistentEpcNumber() + val epcNotFoundPage = assertPageIs(page, EpcNotFoundFormPagePropertyRegistration::class) + + // EPC not found - render page + assertThat(epcNotFoundPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(epcNotFoundPage.heading).containsText("We could not find your EPC") + assertThat(epcNotFoundPage.certificateNumberText).containsText(NONEXISTENT_EPC_CERTIFICATE_NUMBER) + assertThat(epcNotFoundPage.searchAgainLink).isVisible() + + // Click 'search again' to return to Find Your EPC and re-submit not found + epcNotFoundPage.searchAgainLink.click() + val findYourEpcPageAgain = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) + assertThat(findYourEpcPageAgain.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + whenever( + epcRegisterClient.getByRrn(NONEXISTENT_EPC_CERTIFICATE_NUMBER), + ).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + findYourEpcPageAgain.submitNonexistentEpcNumber() + assertPageIs(page, EpcNotFoundFormPagePropertyRegistration::class).form.submit() + + val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) + + // Is EPC required - render page + assertThat(isEpcRequiredPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") + isEpcRequiredPage.submitEpcRequired() + val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) + + // EPC Missing - render page + assertThat(epcMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + assertThat(epcMissingPage.continueAnywayButton).containsText("Continue anyway") + assertThat( + epcMissingPage.warning, + ).containsText("You can be fined for letting a property that does not meet energy efficiency requirements.") + epcMissingPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + assertPageIs(page, TaskListPagePropertyRegistration::class) + } - // The label uses a non-breaking space so "Not required" doesn't wrap onto two lines when hint text is present - assertEquals("Not\u00A0required", tenancyDetailsTask.statusText.trim()) - assertEquals( - "We’ll ask for tenancy details when your property becomes occupied", - tenancyDetailsTask.hintText.trim(), - ) - assertFalse(tenancyDetailsTask.hasLink) - - val checkAndSubmitTask = taskListPage.getSubmitYourRegistrationTask("Check and submit your answers") - assertTrue(checkAndSubmitTask.hasLink) - taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - // Bedrooms is collected as a property detail for all properties, so it is shown on the CYA even when unoccupied - assertThat(checkAnswersPage.summaryList.numberOfBedroomsRow.value).containsText("3") - } - - @Test - @Suppress("ktlint:standard:max-line-length") - fun `restructured occupied journey reaches check answers after EPC and tenancy details`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPage.clickAboutYourPropertyTaskWithName("Property details") - val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") - val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) - selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") - val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) - propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) - val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) - bedroomsPage.submitNumOfBedrooms(3) - val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) - ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) - - val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - hasJointLandlordsPage.submitHasNoJointLandlords() - - val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") - occupancyPage.submitIsOccupied() - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") - licensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) - val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") - hasGasSupplyPage.submitHasNoGasSupply() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - assertThat(checkGasSafetyAnswersPage.sectionHeader).isHidden() - checkGasSafetyAnswersPage.form.submit() - - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPage.clickRentedOutTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - hasElectricalCertPage.submitProvideThisLater() - val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) - provideElectricalCertLaterPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - assertThat(checkElectricalSafetyAnswersPage.sectionHeader).isHidden() - - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - checkElectricalSafetyAnswersPage.form.submit() - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPage.clickRentedOutTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - hasEpcPage.submitProvideThisLater() - val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) - provideEpcLaterPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - assertThat(checkEpcAnswersPage.sectionHeader).isHidden() - checkEpcAnswersPage.form.submit() - - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - assertTrue(taskListPage.getRentedOutTask("Tenancy details").hasLink) - taskListPage.clickRentedOutTaskWithName("Tenancy details") - val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) - householdsPage.submitNumberOfHouseholds(2) - val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) - peoplePage.submitNumOfPeople(2) - val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) - rentIncludesBillsPage.submitIsNotIncluded() - val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) - furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) - val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) - rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) - rentAmountPage.submitRentAmount("400") - - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - } - - @Test - fun `restructured task list shows grouping tasks as cannot start yet until unlocked on a new journey`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - val propertyDetailsTask = taskListPage.getAboutYourPropertyTask("Property details") - assertEquals("Not started", propertyDetailsTask.statusText.trim()) - assertTrue(propertyDetailsTask.hasLink) - - val ownershipTask = taskListPage.getAboutYourPropertyTask("Ownership and landlords") - assertEquals("Cannot start yet", ownershipTask.statusText.trim()) - assertFalse(ownershipTask.hasLink) - - assertEquals("Cannot start yet", taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Tell us if your property needs a license").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Gas safety certificate").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Tenancy details").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getSubmitYourRegistrationTask("Check and submit your answers").statusText.trim()) - } - - @Test - fun `restructured task list shows a grouping task as in progress when it is partially completed`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - - // The address and property type have been answered, but not the number of bedrooms, so the "Property details" - // grouping task (which now contains all three) is partway through. - val taskListPage = - navigator.goToRestructuredPropertyRegistrationTaskList( - PropertyStateSessionBuilder.beforePropertyRegistrationOwnershipType(), - ) - - assertEquals("In progress", taskListPage.getAboutYourPropertyTask("Property details").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getAboutYourPropertyTask("Ownership and landlords").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Gas safety certificate").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getSubmitYourRegistrationTask("Check and submit your answers").statusText.trim()) - } - - @Test - fun `restructured task list shows grouping tasks as complete when their answers are provided`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - - navigator.skipToPropertyRegistrationCheckAnswersPageOccupied() - val taskListPage = navigator.goToPropertyRegistrationTaskList() - - assertEquals("Completed", taskListPage.getAboutYourPropertyTask("Property details").statusText.trim()) - assertEquals("Completed", taskListPage.getAboutYourPropertyTask("Ownership and landlords").statusText.trim()) - assertEquals("Completed", taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.trim()) - assertEquals("Completed", taskListPage.getRentedOutTask("Tenancy details").statusText.trim()) - - val checkAndSubmitTask = taskListPage.getSubmitYourRegistrationTask("Check and submit your answers") - assertEquals("Not started", checkAndSubmitTask.statusText.trim()) - assertTrue(checkAndSubmitTask.hasLink) - } - - @Test - fun `numeric values with leading zeros are displayed without leading zeros on the CYA page`(page: Page) { - val checkAnswersPage = - navigator.skipToPropertyRegistrationCheckAnswersPageOccupied( - households = 2, - people = 4, - bedrooms = 3, - rentAmount = "0000000.1", - ) - - assertThat(checkAnswersPage.summaryList.rentAmountRow.value).containsText("£0.1") - assertThat(checkAnswersPage.summaryList.numberOfHouseholdsRow.value).containsText("2") - assertThat(checkAnswersPage.summaryList.numberOfTenantsRow.value).containsText("4") - assertThat(checkAnswersPage.summaryList.numberOfBedroomsRow.value).containsText("3") - } - - @Test - fun `CYA joint landlords row shows a change link to the check joint landlords page when landlords are invited`(page: Page) { - val taskListPage = - navigator.goToRestructuredPropertyRegistrationTaskList( - PropertyStateSessionBuilder - .beforePropertyRegistrationCheckAnswersOccupied() - .withCheckedJointLandlords(mutableListOf("email@address.com")), - ) - taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - val changeLink = - checkAnswersPage.summaryList.jointLandlordsInvitationsRow.actions - .getActionLink("Change") - assertThat(changeLink).isVisible() - - changeLink.clickAndWait() - val checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordsPage.summaryList.firstRow.value).containsText("email@address.com") - } - - @Test - fun `CYA joint landlords row shows a change link to the has joint landlords page when there are no joint landlords`(page: Page) { - val taskListPage = - navigator.goToRestructuredPropertyRegistrationTaskList( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckAnswersOccupied(), - ) - taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - val changeLink = - checkAnswersPage.summaryList.jointLandlordsAreThereRow.actions - .getActionLink("Change") - assertThat(changeLink).isVisible() - - changeLink.clickAndWait() - assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - } - - @Test - fun `a landlord cannot invite themselves as a joint landlord`(page: Page) { - val inviteJointLandlordPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - - inviteJointLandlordPage.submitEmail("alex.surname@example.com") - - val inviteJointLandlordPageWithError = assertPageIs(page, InviteJointLandlordFormPagePropertyRegistration::class) - assertThat(inviteJointLandlordPageWithError.form.getErrorMessage()) - .containsText("You cannot invite yourself as a joint landlord") - - inviteJointLandlordPageWithError.submitEmail("someone.else@example.com") - assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - } + @Test + fun `User can navigate the MEES flow when they have a MEES exemption`(page: Page) { + val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() + + // Has MEES Exemption - render page + assertThat(hasMeesExemptionPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasMeesExemptionPage.heading).containsText("You need a registered energy efficiency exemption to let this property") + hasMeesExemptionPage.submitHasMeesExemption() + val meesExemptionPage = assertPageIs(page, MeesExemptionFormPagePropertyRegistration::class) + + // MEES Exemption - select exemption reason + assertThat(meesExemptionPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + meesExemptionPage.submitExemptionReason(MeesExemptionReason.HIGH_COST) + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + } + + @Test + fun `User can navigate the MEES flow when they do not have a MEES exemption`(page: Page) { + val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() + + // Has MEES Exemption - submit no exemption + assertThat(hasMeesExemptionPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasMeesExemptionPage.submitHasNoMeesExemption() + val lowEnergyRatingPage = assertPageIs(page, LowEnergyRatingFormPagePropertyRegistration::class) + + // Low Energy Rating - render page + assertThat(lowEnergyRatingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(lowEnergyRatingPage.heading).containsText("This property does not meet energy efficiency requirements for letting") + lowEnergyRatingPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + } + + @Test + fun `User can navigate the EPC exemption flow`(page: Page) { + val epcExemptionPage = navigator.skipToPropertyRegistrationEpcExemptionPage() + + // EPC Exemption - select exemption reason + assertThat(epcExemptionPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + epcExemptionPage.submitExemptionReason(EpcExemptionReason.PROTECTED_ARCHITECTURAL_OR_HISTORICAL_MERIT) + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + } + + @Test + fun `task list back link navigates to start page after entering from start page`(page: Page) { + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.backLink.clickAndWait() + assertPageIs(page, RegisterPropertyStartPage::class) + } + + @Test + fun `task list back link navigates to start page after entering from start page and returning from a task`(page: Page) { + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.clickRegisterTaskWithName("Property address") + assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + + val backLink = BackLink.default(page) + backLink.clickAndWait() + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.backLink.clickAndWait() + assertPageIs(page, RegisterPropertyStartPage::class) + } + + @Test + fun `restructured task list shows three sections with expected task order`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + assertEquals(3, taskListPage.getSectionCount()) + assertThat(taskListPage.getSectionHeading(0)).hasText("About your property") + assertThat(taskListPage.getSectionHeading(1)).hasText("How your property’s rented out") + assertThat(taskListPage.getSectionHeading(2)).hasText("Submit your registration") + assertEquals( + listOf("Property details", "Ownership and landlords", "Tell us if your property’s occupied"), + taskListPage.getAboutYourPropertyTaskNames(), + ) + assertEquals( + listOf( + "Tell us if your property needs a license", + "Gas safety certificate", + "Electrical safety certificate", + "Energy performance certificate (EPC)", + "Tenancy details", + ), + taskListPage.getRentedOutTaskNames(), + ) + assertEquals( + listOf("Check and submit your answers"), + taskListPage.getSubmitYourRegistrationTaskNames(), + ) + + assertTrue(taskListPage.getAboutYourPropertyTask("Property details").hasLink) + taskListPage.clickAboutYourPropertyTaskWithName("Property details") + assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + } + + @Test + fun `restructured task list shows tenancy details as not required when the property is unoccupied`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + val taskListPage = navigator.goToRestructuredPropertyRegistrationTaskListUnoccupied() + val tenancyDetailsTask = taskListPage.getRentedOutTask("Tenancy details") + + // The label uses a non-breaking space so "Not required" doesn't wrap onto two lines when hint text is present + assertEquals("Not\u00A0required", tenancyDetailsTask.statusText.trim()) + assertEquals( + "We’ll ask for tenancy details when your property becomes occupied", + tenancyDetailsTask.hintText.trim(), + ) + assertFalse(tenancyDetailsTask.hasLink) + + val checkAndSubmitTask = taskListPage.getSubmitYourRegistrationTask("Check and submit your answers") + assertTrue(checkAndSubmitTask.hasLink) + taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + // Bedrooms is collected as a property detail for all properties, so it is shown on the CYA even when unoccupied + assertThat(checkAnswersPage.summaryList.numberOfBedroomsRow.value).containsText("3") + } + + @Test + @Suppress("ktlint:standard:max-line-length") + fun `restructured occupied journey reaches check answers after EPC and tenancy details`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.clickAboutYourPropertyTaskWithName("Property details") + val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") + val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) + selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") + val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) + propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) + val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) + bedroomsPage.submitNumOfBedrooms(3) + val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) + + val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + hasJointLandlordsPage.submitHasNoJointLandlords() + + val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") + occupancyPage.submitIsOccupied() + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") + licensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") + hasGasSupplyPage.submitHasNoGasSupply() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + assertThat(checkGasSafetyAnswersPage.sectionHeader).isHidden() + checkGasSafetyAnswersPage.form.submit() + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickRentedOutTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + hasElectricalCertPage.submitProvideThisLater() + val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) + provideElectricalCertLaterPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + assertThat(checkElectricalSafetyAnswersPage.sectionHeader).isHidden() + + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + checkElectricalSafetyAnswersPage.form.submit() + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickRentedOutTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + hasEpcPage.submitProvideThisLater() + val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) + provideEpcLaterPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + assertThat(checkEpcAnswersPage.sectionHeader).isHidden() + checkEpcAnswersPage.form.submit() + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + assertTrue(taskListPage.getRentedOutTask("Tenancy details").hasLink) + taskListPage.clickRentedOutTaskWithName("Tenancy details") + val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) + householdsPage.submitNumberOfHouseholds(2) + val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) + peoplePage.submitNumOfPeople(2) + val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) + rentIncludesBillsPage.submitIsNotIncluded() + val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) + furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) + val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) + rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) + rentAmountPage.submitRentAmount("400") + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + } + + @Test + fun `restructured occupied journey supports provide licensing later and shows it on check answers`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.clickAboutYourPropertyTaskWithName("Property details") + val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") + val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) + selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") + val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) + propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) + val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) + bedroomsPage.submitNumOfBedrooms(3) + val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) + + val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + hasJointLandlordsPage.submitHasNoJointLandlords() + + val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + occupancyPage.submitIsOccupied() + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + licensingTypePage.submitProvideThisLater() + val provideLicensingLaterPage = assertPageIs(page, ProvideLicensingLaterFormPagePropertyRegistration::class) + assertThat(provideLicensingLaterPage.insetText).isVisible() + provideLicensingLaterPage.form.submit() + + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + hasGasSupplyPage.submitHasNoGasSupply() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + checkGasSafetyAnswersPage.form.submit() + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickRentedOutTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + hasElectricalCertPage.submitProvideThisLater() + val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) + provideElectricalCertLaterPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + checkElectricalSafetyAnswersPage.form.submit() + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickRentedOutTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + hasEpcPage.submitProvideThisLater() + val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) + provideEpcLaterPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + checkEpcAnswersPage.form.submit() + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickRentedOutTaskWithName("Tenancy details") + val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) + householdsPage.submitNumberOfHouseholds(2) + val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) + peoplePage.submitNumOfPeople(2) + val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) + rentIncludesBillsPage.submitIsNotIncluded() + val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) + furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) + val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) + rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) + rentAmountPage.submitRentAmount("400") + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + assertThat(checkAnswersPage.summaryList.licensingRow.value).containsText("Provide this later") + } + + @Test + fun `restructured task list shows grouping tasks as cannot start yet until unlocked on a new journey`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + val propertyDetailsTask = taskListPage.getAboutYourPropertyTask("Property details") + assertEquals("Not started", propertyDetailsTask.statusText.trim()) + assertTrue(propertyDetailsTask.hasLink) + + val ownershipTask = taskListPage.getAboutYourPropertyTask("Ownership and landlords") + assertEquals("Cannot start yet", ownershipTask.statusText.trim()) + assertFalse(ownershipTask.hasLink) + + assertEquals("Cannot start yet", taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Tell us if your property needs a license").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Gas safety certificate").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Tenancy details").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getSubmitYourRegistrationTask("Check and submit your answers").statusText.trim()) + } + + @Test + fun `restructured task list shows a grouping task as in progress when it is partially completed`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + // The address and property type have been answered, but not the number of bedrooms, so the "Property details" + // grouping task (which now contains all three) is partway through. + val taskListPage = + navigator.goToRestructuredPropertyRegistrationTaskList(PropertyStateSessionBuilder.beforePropertyRegistrationOwnershipType()) + + assertEquals("In progress", taskListPage.getAboutYourPropertyTask("Property details").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getAboutYourPropertyTask("Ownership and landlords").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Gas safety certificate").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getSubmitYourRegistrationTask("Check and submit your answers").statusText.trim()) + } + + @Test + fun `restructured task list shows grouping tasks as complete when their answers are provided`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + navigator.skipToPropertyRegistrationCheckAnswersPageOccupied() + val taskListPage = navigator.goToPropertyRegistrationTaskList() + + assertEquals("Completed", taskListPage.getAboutYourPropertyTask("Property details").statusText.trim()) + assertEquals("Completed", taskListPage.getAboutYourPropertyTask("Ownership and landlords").statusText.trim()) + assertEquals("Completed", taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.trim()) + assertEquals("Completed", taskListPage.getRentedOutTask("Tenancy details").statusText.trim()) + + val checkAndSubmitTask = taskListPage.getSubmitYourRegistrationTask("Check and submit your answers") + assertEquals("Not started", checkAndSubmitTask.statusText.trim()) + assertTrue(checkAndSubmitTask.hasLink) } companion object { @@ -1717,1360 +1723,60 @@ class PropertyRegistrationJourneyTests : IntegrationTestWithMutableData("data-lo val uprnForSelectedAddress = 1L // This matches the uprn in data-local.sql for address 1 Fictional Road, FA1 1AA } - // TODO PDJB-1340: Remove tests when the PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING Feature Flag is removed - @Nested - inner class RestructureAndSkippingDisabled { - private val propertyRegistrationSectionHeader = "Section 1 of 2 — Add property details" - - @BeforeEach - fun disableRestructureAndSkippingFlag() { - featureFlagManager.disableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - } - - @Test - @Suppress("ktlint:standard:max-line-length") - fun `User can navigate the whole journey if pages are correctly filled in (select address, non-custom property type, selective license, occupied, compliance certificates uploaded)`( - page: Page, - ) { - // Start page (not a journey step, but it is how the user accesses the journey) - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - assertThat(registerPropertyStartPage.heading).containsText("Register a property") - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // Task list page (part of the journey to support redirects) - taskListPage.clickRegisterTaskWithName("Property address") - val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - - // Address lookup - render page - assertThat(addressLookupPage.form.fieldsetHeading).containsText("What is the property address?") - assertThat(addressLookupPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") - val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) - - // Select address - render page - assertThat(selectAddressPage.form.fieldsetHeading).containsText("Select your address") - assertThat(selectAddressPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") - val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) - - // Verify incomplete property is created at this point - verify(landlordIncompletePropertiesRepository).save(any()) - - // Property type selection - render page - assertThat(propertyTypePage.form.fieldsetHeading).containsText("What type of property are you registering?") - assertThat(propertyTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) - val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) - - // Ownership type selection - render page - assertThat(ownershipTypePage.form.fieldsetHeading).containsText("Select the type of ownership you have for your property") - assertThat(ownershipTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - - // Licensing type - render page - assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") - assertThat(licensingTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - licensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) - val selectiveLicencePage = assertPageIs(page, SelectiveLicenceFormPagePropertyRegistration::class) - - // Selective licence - render page - assertThat(selectiveLicencePage.form.fieldsetHeading).containsText("What is your selective licence number?") - assertThat(selectiveLicencePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - selectiveLicencePage.submitLicenseNumber("licence number") - val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - - // Occupancy - render page - assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") - assertThat(occupancyPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - occupancyPage.submitIsOccupied() - val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) - - // Number of households - render page - assertThat(householdsPage.header).containsText("Households in your property") - assertThat(householdsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - householdsPage.submitNumberOfHouseholds(2) - val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) - - // Number of people - render page - assertThat(peoplePage.header).containsText("How many people live in your property?") - assertThat(peoplePage.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - peoplePage.submitNumOfPeople(2) - val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) - - // Number of bedrooms - render page - assertThat(bedroomsPage.header).containsText("How many bedrooms in your property?") - assertThat(bedroomsPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - bedroomsPage.submitNumOfBedrooms(3) - val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) - - // Does the rent include bills - render page - assertThat(rentIncludesBillsPage.form.fieldsetHeading).containsText("Does the rent include bills?") - assertThat(rentIncludesBillsPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - rentIncludesBillsPage.submitIsIncluded() - val billsIncludedPage = assertPageIs(page, BillsIncludedFormPagePropertyRegistration::class) - - // Bills included - render page - assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Which of these do you include in the rent?") - assertThat(billsIncludedPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.selectSomethingElseCheckbox() - billsIncludedPage.fillCustomBills("Dog Grooming") - billsIncludedPage.form.submit() - val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) - - // Furnished - render page - assertThat(furnishedPage.form.fieldsetHeading).containsText("Is the property furnished?") - assertThat(furnishedPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) - val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) - - // Rent frequency - render page - assertThat(rentFrequencyPage.header).containsText("When you charge rent") - assertThat(rentFrequencyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - rentFrequencyPage.selectRentFrequency(RentFrequency.OTHER) - rentFrequencyPage.fillCustomRentFrequency("Fortnightly") - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) - - // Rent amount - render page - assertThat(rentAmountPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - rentAmountPage.submitRentAmount("400") - val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - - // Has Joint Landlords - render page - assertThat(hasJointLandlordsPage.header).containsText("Invite joint landlords") - assertThat(hasJointLandlordsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - - // fill in and submit - hasJointLandlordsPage.submitHasJointLandlords() - val inviteJointLandlordPage = assertPageIs(page, InviteJointLandlordFormPagePropertyRegistration::class) - - // Invite joint landlord - render page - assertThat(inviteJointLandlordPage.heading).containsText("Invite a joint landlord to this property") - assertThat(inviteJointLandlordPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - - // fill in and submit - inviteJointLandlordPage.submitEmail("email@address.com") - var checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(checkJointLandlordsPage.summaryList.firstRow.value).containsText("email@address.com") - - // Check joint landlords - render page - checkJointLandlordsPage - .form - .addAnotherButton - .clickAndWait() - - // Invite another joint landlord - render page - val addAnotherPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - assertThat(addAnotherPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - addAnotherPage.submitEmail("email2@address.com") - - checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordsPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - - // Remove Joint Landlord - render page - val removeJointLandlordsPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordsPage.submitWantsToProceed() - - checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordsPage.form.submit() - - val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - - // Has Gas Supply - render page - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert - render page - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasGasCertPage.heading).containsText("Do you have a gas safety certificate for this property?") - hasGasCertPage.submitHasCertificate() - val gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page - assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") - gasCertIssueDatePage.submitDate(validGasSafetyCertIssueDate) - var uploadGasCertPage = assertPageIs(page, UploadGasCertFormPagePropertyRegistration::class) - - // Upload Gas Cert - render page - assertThat(uploadGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - uploadGasCertPage.uploadGasCertificate(Path.of("src/test/resources/test-files/blank.png")) - var checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) - - // Check Gas Cert Uploads - render page - assertThat(checkGasCertUploadsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(checkGasCertUploadsPage.heading).containsText("You’ve uploaded 1 file") - assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - assertEquals(checkGasCertUploadsPage.table.rows.count(), 1) - checkGasCertUploadsPage.form.addAnotherButton.clickAndWait() - uploadGasCertPage = assertPageIs(page, UploadGasCertFormPagePropertyRegistration::class) - - uploadGasCertPage.uploadGasCertificate(Path.of("src/test/resources/test-files/blank.png")) - checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) - - assertThat(checkGasCertUploadsPage.heading).containsText("You’ve uploaded 2 files") - assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - assertThat(checkGasCertUploadsPage.table.getCell(1, 0)).containsText("blank.png") - assertEquals(checkGasCertUploadsPage.table.rows.count(), 2) - - checkGasCertUploadsPage.table - .getClickableCell(0, 2) - .link - .clickAndWait() - - val removeGasCertUploadPage = assertPageIs(page, RemoveGasCertUploadFormPagePropertyRegistration::class) - - removeGasCertUploadPage.form.radios.selectValue("true") - removeGasCertUploadPage.form.submit() - - checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) - assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - - assertEquals(checkGasCertUploadsPage.table.rows.count(), 1) - checkGasCertUploadsPage.form.submit() - - // Remove Gas Cert Upload - render page - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasEic() - val electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date - render page - assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat( - electricalCertExpiryDatePage.heading, - ).containsText("What’s the expiry date on the Electrical Installation Certificate?") - electricalCertExpiryDatePage.submitDate(validExpiryDate) - var uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) - - // Upload Electrical Cert - render page - assertThat(uploadElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) - var checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) - - // Check Electrical Cert Uploads - render page - assertThat(checkElectricalCertUploadsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 1) - checkElectricalCertUploadsPage.form.addAnotherButton.clickAndWait() - uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) - - uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) - checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) - assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - assertThat(checkElectricalCertUploadsPage.table.getCell(1, 0)).containsText("blank.png") - assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 2) - - checkElectricalCertUploadsPage.table - .getClickableCell(0, 2) - .link - .clickAndWait() - - val removeElectricalCertUploadPage = assertPageIs(page, RemoveElectricalCertUploadFormPagePropertyRegistration::class) - - removeElectricalCertUploadPage.form.radios.selectValue("true") - removeElectricalCertUploadPage.form.submit() - - checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) - assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - - assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 1) - checkElectricalCertUploadsPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep being able to find an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)) - .thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - expiryDate = validExpiryDate, - ), - ) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // EpcLookupByUprnStep finds the EPC, so redirects to Check UPRN matched EPC - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val confirmUprnMatchedEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) - - // Confirm UPRN matched EPC - submit No (don't use this EPC) - assertThat(confirmUprnMatchedEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - confirmUprnMatchedEpcDetailsPage.submitNo() - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasEpcPage.submitHasEpc() - val findYourEpcPage = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) - - // EPC Search - render page - assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - whenever(epcRegisterClient.getByRrn(CURRENT_EPC_CERTIFICATE_NUMBER)) - .thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - certificateNumber = CURRENT_EPC_CERTIFICATE_NUMBER, - latestCertificateNumberForThisProperty = CURRENT_EPC_CERTIFICATE_NUMBER, - expiryDate = validExpiryDate, - ), - ) - findYourEpcPage.submitCurrentEpcNumber() - val confirmEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByCertificateNumberPagePropertyRegistration::class) - - // Check Matched EPC - render page - assertThat(confirmEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - val expectedExpiryDate = - validExpiryDate - .toJavaLocalDate() - .format(DateTimeFormatter.ofPattern("d MMMM yyyy")) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.addressRow.value).containsText(MockEpcData.defaultSingleLineAddress) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.energyEfficiencyRatingRow.value).containsText("C") - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.expiryDateRow.value).containsText(expectedExpiryDate) - assertThat( - confirmEpcDetailsPage.summaryCard.summaryList.certificateNumberRow.value, - ).containsText(CURRENT_EPC_CERTIFICATE_NUMBER) - confirmEpcDetailsPage.submitYes() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - // Check answers - render page - assertThat(checkAnswersPage.heading).containsText("Check your answers for:") - assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") - assertThat(checkAnswersPage.complianceCertificatesHeading).isVisible() - assertThat(checkAnswersPage.gasSafetyHeading).isVisible() - assertThat(checkAnswersPage.electricalSafetyHeading).isVisible() - assertThat(checkAnswersPage.epcHeading).isVisible() - // submit - checkAnswersPage.confirm() - val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) - - // Confirmation - render page - val propertyOwnershipCaptor = captor() - verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) - val expectedPropertyRegNum = - RegistrationNumberDataModel.fromRegistrationNumber( - propertyOwnershipCaptor.value.registrationNumber, - ) - assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) - assertTrue(propertyOwnershipCaptor.value.isOccupied) - assertFalse(confirmationPage.whatYouNeedToDoNextHeading.isVisible) - assertTrue(confirmationPage.surveyLink.locator.isVisible) - assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) - - // Check confirmation email - verify(confirmationEmailSender).sendEmail( - "alex.surname@example.com", - PropertyRegistrationConfirmationEmail( - expectedPropertyRegNum.toString(), - "1 Fictional Road, FA1 1AA", - absoluteLandlordUrl, - true, - listOf("email2@address.com"), - ), + @Test + fun `numeric values with leading zeros are displayed without leading zeros on the CYA page`(page: Page) { + val checkAnswersPage = + navigator.skipToPropertyRegistrationCheckAnswersPageOccupied( + households = 2, + people = 4, + bedrooms = 3, + rentAmount = "0000000.1", ) - // Go to dashboard - confirmationPage.goToDashboardLink.clickAndWait() - assertPageIs(page, LandlordDashboardPage::class) - } - - @Test - @Suppress("ktlint:standard:max-line-length") - fun `User can navigate the whole journey if pages are correctly filled in (manual address, custom property type, no license, unoccupied, no joint landlords, no certificates)`( - page: Page, - ) { - // Start page (not a journey step, but it is how the user accesses the journey) - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - assertThat(registerPropertyStartPage.heading).containsText("Register a property") - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // Task list page (part of the journey to support redirects) - taskListPage.clickRegisterTaskWithName("Property address") - val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - - // Address lookup - render page - assertThat(addressLookupPage.form.fieldsetHeading).containsText("What is the property address?") - assertThat(addressLookupPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AB", "2") - val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) - - // Select address - render page - assertThat(selectAddressPage.form.fieldsetHeading).containsText("Select your address") - assertThat(selectAddressPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - selectAddressPage.selectAddressAndSubmit(MANUAL_ADDRESS_CHOSEN) - val manualAddressPage = assertPageIs(page, ManualAddressFormPagePropertyRegistration::class) - - // Manual address - render page - assertThat(manualAddressPage.form.fieldsetHeading).containsText("What is the property address?") - assertThat(manualAddressPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - manualAddressPage.submitAddress(addressLineOne = "Test address line 1", townOrCity = "Testville", postcode = "EG1 2AB") - val selectLocalCouncilPage = assertPageIs(page, SelectLocalCouncilFormPagePropertyRegistration::class) - - // Select local council - render page - assertThat(selectLocalCouncilPage.form.fieldsetHeading).containsText("What local council area is your property in?") - assertThat(selectLocalCouncilPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - selectLocalCouncilPage.submitLocalCouncil("BATH AND NORTH EAST SOMERSET COUNCIL", "BATH AND NORTH EAST SOMERSET COUNCIL") - val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) - - // Property type selection - render page - assertThat(propertyTypePage.form.fieldsetHeading).containsText("What type of property are you registering?") - assertThat(propertyTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - propertyTypePage.submitCustomPropertyType("End terrace house") - val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) - - // Ownership type selection - render page - assertThat(ownershipTypePage.form.fieldsetHeading).containsText("Select the type of ownership you have for your property") - assertThat(ownershipTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - - // Licensing type - render page - assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") - assertThat(licensingTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - licensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) - val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - - // Occupancy - render page - assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") - assertThat(occupancyPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - occupancyPage.submitIsVacant() - val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - - // Has Joint Landlords - render page - assertThat(hasJointLandlordsPage.header).containsText("Invite joint landlords") - assertThat(hasJointLandlordsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - - // fill in and submit - hasJointLandlordsPage.submitHasNoJointLandlords() - val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - - // Has Gas Supply - render page - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert - render page - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasGasCertPage.heading).containsText("Do you have a gas safety certificate for this property?") - hasGasCertPage.submitHasNoCertificate() - val gasCertMissingPage = assertPageIs(page, GasCertMissingFormPagePropertyRegistration::class) - - // Gas Cert Missing - render page - assertThat(gasCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertMissingPage.heading).containsText("You must get a gas safety certificate before a tenant moves in") - assertThat(gasCertMissingPage.warning).isHidden() - assertThat(gasCertMissingPage.submitButton).containsText("Continue") - gasCertMissingPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasNoCert() - val electricalCertMissingPage = assertPageIs(page, ElectricalCertMissingFormPagePropertyRegistration::class) - - // Electrical Cert Missing - render page - assertThat(electricalCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat( - electricalCertMissingPage.heading, - ).containsText("You must get an electrical safety certificate before a tenant moves in") - assertThat(electricalCertMissingPage.warning).isHidden() - assertThat(electricalCertMissingPage.submitButton).containsText("Continue") - electricalCertMissingPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // We use a manual address, uprn will be null. - // The internal EpcLookupByUprnStep at the start of the EpcTask will not find an EPC - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasEpcPage.submitHasNoEpc() - val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) - - // Is EPC required - render page - assertThat(isEpcRequiredPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") - isEpcRequiredPage.submitEpcRequired() - val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) - - // EPC Missing - render page - assertThat(epcMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - assertThat(epcMissingPage.continueButton).containsText("Continue") - assertThat(epcMissingPage.warning).isHidden() - epcMissingPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - // Check answers - render page - assertThat(checkAnswersPage.heading).containsText("Check your answers for:") - assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") - // submit - checkAnswersPage.confirm() - val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) - - // Confirmation - render page - val propertyOwnershipCaptor = captor() - verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) - val expectedPropertyRegNum = - RegistrationNumberDataModel.fromRegistrationNumber( - propertyOwnershipCaptor.value.registrationNumber, - ) - assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) - assertFalse(propertyOwnershipCaptor.value.isOccupied) - assertTrue(confirmationPage.whatYouNeedToDoNextHeading.isHidden) - assertTrue(confirmationPage.surveyLink.locator.isVisible) - assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) - - // Check confirmation email - verify(confirmationEmailSender).sendEmail( - "alex.surname@example.com", - PropertyRegistrationConfirmationEmail( - expectedPropertyRegNum.toString(), - "Test address line 1, Testville, EG1 2AB", - absoluteLandlordUrl, - false, - null, - ), - ) + assertThat(checkAnswersPage.summaryList.rentAmountRow.value).containsText("£0.1") + assertThat(checkAnswersPage.summaryList.numberOfHouseholdsRow.value).containsText("2") + assertThat(checkAnswersPage.summaryList.numberOfTenantsRow.value).containsText("4") + assertThat(checkAnswersPage.summaryList.numberOfBedroomsRow.value).containsText("3") + } - // Go to dashboard - confirmationPage.goToDashboardLink.clickAndWait() - assertPageIs(page, LandlordDashboardPage::class) - } - - @Test - fun `User can choose to provide compliance certificates later if their property is occupied`(page: Page) { - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert. Submit with no option selected - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasCertPage.submitProvideThisLater() - val provideGasCertLaterPage = assertPageIs(page, ProvideGasCertLaterFormPagePropertyRegistration::class) - - // Provide Gas Cert Later - render page - assertThat(provideGasCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(provideGasCertLaterPage.insetText).containsText("You must upload your gas safety certificate within 28 days") - provideGasCertLaterPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasElectricalCertPage.submitProvideThisLater() - val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) - - // Provide Electrical Cert Later - render page - assertThat(provideElectricalCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat( - provideElectricalCertLaterPage.insetText, - ).containsText("You must upload your electrical safety certificate within 28 days.") - provideElectricalCertLaterPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasEpcPage.submitProvideThisLater() - val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) - - // Provide EPC Later - render page - assertThat(provideEpcLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") - assertThat(provideEpcLaterPage.insetText).containsText( - "To keep the property registered, we need all its compliance certificates within 28 days.", - ) - provideEpcLaterPage.form.submit() - - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - assertPageIs(page, TaskListPagePropertyRegistration::class) - } - - @Test - fun `User can choose to provide compliance certificates later if their property is unoccupied`(page: Page) { - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = false) - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert. Submit with no option selected - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasCertPage.submitProvideThisLater() - val provideGasCertLaterPage = assertPageIs(page, ProvideGasCertLaterFormPagePropertyRegistration::class) - - // Provide Gas Cert Later - render page - assertThat(provideGasCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(provideGasCertLaterPage.insetText).isHidden() - assertTrue( - provideGasCertLaterPage.page - .content() - .contains("You must get a gas safety certificate before a tenant moves in."), - ) - provideGasCertLaterPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasElectricalCertPage.submitProvideThisLater() - val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) - - // Provide Electrical Cert Later - render page (unoccupied variant) - assertThat(provideElectricalCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(provideElectricalCertLaterPage.heading).containsText("Provide your electrical safety certificate later") - assertThat(provideElectricalCertLaterPage.insetText).isHidden() - assertTrue( - provideElectricalCertLaterPage.page - .content() - .contains("You must get an electrical safety certificate before a tenant moves in."), - ) - provideElectricalCertLaterPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasEpcPage.submitProvideThisLater() - val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) - - // Provide EPC Later - render page - assertThat(provideEpcLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") - assertThat(provideEpcLaterPage.insetText).isHidden() - provideEpcLaterPage.form.submit() - - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - assertPageIs(page, TaskListPagePropertyRegistration::class) - } - - @Test - fun `User can complete the journey with missing compliance certificates for an occupied property`(page: Page) { - // Gas supply page - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert page - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasCertPage.submitHasNoCertificate() - val gasCertMissingPage = assertPageIs(page, GasCertMissingFormPagePropertyRegistration::class) - - // Gas Cert Missing - render page - assertThat(gasCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertMissingPage.heading).containsText("You must get a valid gas safety certificate for this property") - assertThat(gasCertMissingPage.submitButton).containsText("Continue without a valid gas safety certificate") - assertThat(gasCertMissingPage.warning) - .containsText("You could face prosecution if you have tenants in a property without a gas safety certificate") - gasCertMissingPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasNoCert() - val electricalCertMissingPage = assertPageIs(page, ElectricalCertMissingFormPagePropertyRegistration::class) - - assertThat(electricalCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat( - electricalCertMissingPage.heading, - ).containsText("You must get a valid electrical safety certificate for this property") - assertThat(electricalCertMissingPage.warning) - .containsText("You could face prosecution if you have tenants in a property without an electrical safety certificate.") - assertThat(electricalCertMissingPage.submitButton).containsText("Continue without a valid electrical safety certificate") - electricalCertMissingPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasEpcPage.submitHasNoEpc() - val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) - - // Is EPC required - render page - assertThat(isEpcRequiredPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") - isEpcRequiredPage.submitEpcRequired() - val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) - - // EPC Missing - render page - assertThat(epcMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - assertThat(epcMissingPage.continueAnywayButton).containsText("Continue anyway") - assertThat( - epcMissingPage.warning, - ).containsText("You can be fined for letting a property that does not meet energy efficiency requirements.") - epcMissingPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") - - // Check Answers - submit to reach Confirm Missing Compliance page - checkAnswersPage.form.submit() - val confirmMissingCompliancePage = assertPageIs(page, ConfirmMissingComplianceFormPagePropertyRegistration::class) - - // Confirm Missing Compliance - render page - assertThat(confirmMissingCompliancePage.heading).containsText("Confirm missing compliance certificates") - assertThat(confirmMissingCompliancePage.warning).isVisible() - assertThat(confirmMissingCompliancePage.form.sectionHeader).containsText("Submit registration") - - // Confirm Missing Compliance - submit - confirmMissingCompliancePage.form.radios.selectValue("true") - confirmMissingCompliancePage.form.submit() - val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) - - // Confirmation - verify record saved - val propertyOwnershipCaptor = captor() - verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) - val expectedPropertyRegNum = - RegistrationNumberDataModel.fromRegistrationNumber( - propertyOwnershipCaptor.value.registrationNumber, - ) - assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) - assertTrue(confirmationPage.surveyLink.locator.isVisible) - assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) - } - - @Test - fun `User can complete the journey with expired compliance certificates for an occupied property (epc found by uprn)`(page: Page) { - // Gas supply page - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert page - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasCertPage.submitHasCertificate() - var gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page - assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") - gasCertIssueDatePage.submitDate(expiredGasSafetyCertIssueDate) - var gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) - - // Gas Cert Expired - render page then navigate to edit issue date - assertThat(gasCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertExpiredPage.mainHeading).containsText("This gas safety certificate has expired") - assertThat(gasCertExpiredPage.sectionHeading).containsText("You must get a valid gas safety certificate for this property") - assertThat(gasCertExpiredPage.warning) - .containsText("You could face prosecution if you have tenants in a property without a gas safety certificate.") - assertThat(gasCertExpiredPage.submitButton).containsText("Continue without a valid gas safety certificate") - gasCertExpiredPage.changeIssueDateLink.clickAndWait() - gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page, prepopulated with previous value, then submit again - assertThat(gasCertIssueDatePage.form.dayInput).hasValue(expiredGasSafetyCertIssueDate.dayOfMonth.toString()) - assertThat(gasCertIssueDatePage.form.monthInput).hasValue(expiredGasSafetyCertIssueDate.monthNumber.toString()) - assertThat(gasCertIssueDatePage.form.yearInput).hasValue(expiredGasSafetyCertIssueDate.year.toString()) - gasCertIssueDatePage.form.submit() - gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) - - // Back on Gas Cert Expired page - submit - gasCertExpiredPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasEic() - var electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date - render page - assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - electricalCertExpiryDatePage.submitDate(expiredExpiryDate) - var electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) - - // Electrical Cert Expired - render page then check change expiry date link - assertThat(electricalCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(electricalCertExpiredPage.warning) - .containsText("You could face prosecution if you have tenants in a property without an electrical safety certificate.") - assertThat(electricalCertExpiredPage.submitButton).containsText("Continue without a valid electrical safety certificate") - electricalCertExpiredPage.changeExpiryDateLink.clickAndWait() - electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date again - render page, prepopulated with previous value, then submit again - assertThat(electricalCertExpiryDatePage.form.dayInput).hasValue(expiredExpiryDate.dayOfMonth.toString()) - assertThat(electricalCertExpiryDatePage.form.monthInput).hasValue(expiredExpiryDate.monthNumber.toString()) - assertThat(electricalCertExpiryDatePage.form.yearInput).hasValue(expiredExpiryDate.year.toString()) - electricalCertExpiryDatePage.form.submit() - electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) - - // Back on Electrical Cert Expired page - submit - electricalCertExpiredPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep being able to find an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)) - .thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - expiryDate = expiredExpiryDate, - ), - ) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // EpcLookupByUprnStep finds the EPC, so redirects to Check UPRN matched EPCe - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val confirmUprnMatchedEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) - - // Check UPRN matched EPC - submit Yes (accept this expired EPC, which triggers age/rating check internally) - assertThat(confirmUprnMatchedEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - confirmUprnMatchedEpcDetailsPage.submitYes() - val epcExpiryCheckPage = assertPageIs(page, EpcInDateAtStartOfTenancyCheckPagePropertyRegistration::class) - - assertThat(epcExpiryCheckPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - epcExpiryCheckPage.submitEpcExpired() - val epcExpiredPage = assertPageIs(page, EpcExpiredFormPagePropertyRegistration::class) - - // EPC Expired - occupied variant: warning visible, "Continue anyway" button - assertThat(epcExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") - assertThat(epcExpiredPage.warning).isVisible() - assertThat(epcExpiredPage.submitButton).containsText("Continue anyway") - epcExpiredPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") - } - - @Test - fun `User can complete the journey with expired compliance certificates for an unoccupied property (epc not found by uprn)`( - page: Page, - ) { - // Gas supply page - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = false) - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert page - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasCertPage.submitHasCertificate() - var gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page - assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") - gasCertIssueDatePage.submitDate(expiredGasSafetyCertIssueDate) - var gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) - - // Gas Cert Expired - render page then navigate to edit issue date - assertThat(gasCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertExpiredPage.mainHeading).containsText("This gas safety certificate has expired") - assertThat(gasCertExpiredPage.sectionHeading).containsText("What to do next") - assertThat(gasCertExpiredPage.warning).isHidden() - assertThat(gasCertExpiredPage.submitButton).containsText("Save and continue") - gasCertExpiredPage.changeIssueDateLink.clickAndWait() - gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page, prepopulated with previous value, then submit again - assertThat(gasCertIssueDatePage.form.dayInput).hasValue(expiredGasSafetyCertIssueDate.dayOfMonth.toString()) - assertThat(gasCertIssueDatePage.form.monthInput).hasValue(expiredGasSafetyCertIssueDate.monthNumber.toString()) - assertThat(gasCertIssueDatePage.form.yearInput).hasValue(expiredGasSafetyCertIssueDate.year.toString()) - gasCertIssueDatePage.form.submit() - gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) - - // Back on Gas Cert Expired page - submit - gasCertExpiredPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasEic() - var electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date - render page - assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - electricalCertExpiryDatePage.submitDate(expiredExpiryDate) - var electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) - - // Electrical Cert Expired - render page then check change expiry date link - assertThat(electricalCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(electricalCertExpiredPage.warning).isHidden() - assertThat(electricalCertExpiredPage.submitButton).containsText("Save and continue") - electricalCertExpiredPage.changeExpiryDateLink.clickAndWait() - electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date again - render page, prepopulated with previous value, then submit again - assertThat(electricalCertExpiryDatePage.form.dayInput).hasValue(expiredExpiryDate.dayOfMonth.toString()) - assertThat(electricalCertExpiryDatePage.form.monthInput).hasValue(expiredExpiryDate.monthNumber.toString()) - assertThat(electricalCertExpiryDatePage.form.yearInput).hasValue(expiredExpiryDate.year.toString()) - electricalCertExpiryDatePage.form.submit() - electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) - - // Back on Electrical Cert Expired page - submit - electricalCertExpiredPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasEpcPage.submitHasEpc() - val findYourEpcPage = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) - - // EPC Search - render page - assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - whenever(epcRegisterClient.getByRrn(CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER)) - .thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - certificateNumber = CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER, - expiryDate = expiredExpiryDate, - latestCertificateNumberForThisProperty = CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER, - ), - ) - findYourEpcPage.submitCurrentEpcNumberWhichIsExpired() - val confirmEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByCertificateNumberPagePropertyRegistration::class) - - // Check Matched EPC - render page - assertThat(confirmEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - val expectedExpiryDate = - expiredExpiryDate - .toJavaLocalDate() - .format(DateTimeFormatter.ofPattern("d MMMM yyyy")) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.addressRow.value).containsText(MockEpcData.defaultSingleLineAddress) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.energyEfficiencyRatingRow.value).containsText("C") - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.expiryDateRow.value).containsText(expectedExpiryDate) - assertThat( - confirmEpcDetailsPage.summaryCard.summaryList.certificateNumberRow.value, - ).containsText(CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER) - confirmEpcDetailsPage.submitYes() - val epcExpiredPage = assertPageIs(page, EpcExpiredFormPagePropertyRegistration::class) - - // EPC Expired - unoccupied variant: no warning, "Continue" button - assertThat(epcExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") - assertThat(epcExpiredPage.warning).isHidden() - assertThat(epcExpiredPage.submitButton).containsText("Continue") - epcExpiredPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") - } - - @Test - fun `The Electrical Safety task can be completed by the user uploaded an eicr`(page: Page) { - // Skip to Has Electrical Cert page and submit "Yes" - val hasElectricalCertPage = navigator.skipToPropertyRegistrationHasElectricalCertPage() - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasElectricalCertPage.submitHasEicr() - val electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date - render page - assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat( - electricalCertExpiryDatePage.heading, - ).containsText("What’s the expiry date on the Electrical Installation Condition Report?") - electricalCertExpiryDatePage.submitDate(validExpiryDate) - val uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) - - // Upload Electrical Cert - render page - assertThat(uploadElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(uploadElectricalCertPage.heading).containsText("Upload the Electrical Installation Condition Report (EICR)") - uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) - - // Check Electrical Safety Answers - EICR variant verified by heading text - } - - @Test - fun `The EPC task can be completed when FindYourEpc finds a superseded epc`(page: Page) { - // Skip to Find Your EPC page and submit "Superseded EPC Found" - val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() - assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - whenever(epcRegisterClient.getByRrn(SUPERSEDED_EPC_CERTIFICATE_NUMBER)).thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - certificateNumber = SUPERSEDED_EPC_CERTIFICATE_NUMBER, - expiryDate = MockEpcData.expiryDateInThePast, - latestCertificateNumberForThisProperty = CURRENT_EPC_CERTIFICATE_NUMBER, - ), - ) - whenever(epcRegisterClient.getByRrn(CURRENT_EPC_CERTIFICATE_NUMBER)).thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - certificateNumber = CURRENT_EPC_CERTIFICATE_NUMBER, - ), - ) - findYourEpcPage.submitSupersededEpcNumber() - val epcSupersededPage = assertPageIs(page, EpcSuperseededFormPagePropertyRegistration::class) - - // Check details of superseded and latest epc - render page - assertThat(epcSupersededPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - epcSupersededPage.submitContinueWithLatest() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - assertPageIs(page, TaskListPagePropertyRegistration::class) - } - - @Test - fun `The EPC task can be completed when FindYourEpc finds no epc and it is missing`(page: Page) { - // Skip to Find Your EPC page and submit "No EPC Found" - val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() - assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - whenever( - epcRegisterClient.getByRrn(NONEXISTENT_EPC_CERTIFICATE_NUMBER), - ).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - findYourEpcPage.submitNonexistentEpcNumber() - val epcNotFoundPage = assertPageIs(page, EpcNotFoundFormPagePropertyRegistration::class) - - // EPC not found - render page - assertThat(epcNotFoundPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(epcNotFoundPage.heading).containsText("We could not find your EPC") - assertThat(epcNotFoundPage.certificateNumberText).containsText(NONEXISTENT_EPC_CERTIFICATE_NUMBER) - assertThat(epcNotFoundPage.searchAgainLink).isVisible() - - // Click 'search again' to return to Find Your EPC and re-submit not found - epcNotFoundPage.searchAgainLink.click() - val findYourEpcPageAgain = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) - assertThat(findYourEpcPageAgain.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - whenever( - epcRegisterClient.getByRrn(NONEXISTENT_EPC_CERTIFICATE_NUMBER), - ).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - findYourEpcPageAgain.submitNonexistentEpcNumber() - assertPageIs(page, EpcNotFoundFormPagePropertyRegistration::class).form.submit() - - val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) - - // Is EPC required - render page - assertThat(isEpcRequiredPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") - isEpcRequiredPage.submitEpcRequired() - val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) - - // EPC Missing - render page - assertThat(epcMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - assertThat(epcMissingPage.continueAnywayButton).containsText("Continue anyway") - assertThat( - epcMissingPage.warning, - ).containsText("You can be fined for letting a property that does not meet energy efficiency requirements.") - epcMissingPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - assertPageIs(page, TaskListPagePropertyRegistration::class) - } - - @Test - fun `User can navigate the MEES flow when they have a MEES exemption`(page: Page) { - val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() - - // Has MEES Exemption - render page - assertThat(hasMeesExemptionPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasMeesExemptionPage.heading).containsText("You need a registered energy efficiency exemption to let this property") - hasMeesExemptionPage.submitHasMeesExemption() - val meesExemptionPage = assertPageIs(page, MeesExemptionFormPagePropertyRegistration::class) - - // MEES Exemption - select exemption reason - assertThat(meesExemptionPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - meesExemptionPage.submitExemptionReason(MeesExemptionReason.HIGH_COST) - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - } - - @Test - fun `User can navigate the MEES flow when they do not have a MEES exemption`(page: Page) { - val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() - - // Has MEES Exemption - submit no exemption - assertThat(hasMeesExemptionPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasMeesExemptionPage.submitHasNoMeesExemption() - val lowEnergyRatingPage = assertPageIs(page, LowEnergyRatingFormPagePropertyRegistration::class) - - // Low Energy Rating - render page - assertThat(lowEnergyRatingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(lowEnergyRatingPage.heading).containsText("This property does not meet energy efficiency requirements for letting") - lowEnergyRatingPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - } - - @Test - fun `User can navigate the EPC exemption flow`(page: Page) { - val epcExemptionPage = navigator.skipToPropertyRegistrationEpcExemptionPage() - - // EPC Exemption - select exemption reason - assertThat(epcExemptionPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - epcExemptionPage.submitExemptionReason(EpcExemptionReason.PROTECTED_ARCHITECTURAL_OR_HISTORICAL_MERIT) - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - } - - @Test - fun `task list back link navigates to start page after entering from start page`(page: Page) { - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPage.backLink.clickAndWait() - assertPageIs(page, RegisterPropertyStartPage::class) - } - - @Test - fun `task list back link navigates to start page after entering from start page and returning from a task`(page: Page) { - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPage.clickRegisterTaskWithName("Property address") - assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - - val backLink = BackLink.default(page) - backLink.clickAndWait() - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPage.backLink.clickAndWait() - assertPageIs(page, RegisterPropertyStartPage::class) - } - - @Test - fun `numeric values with leading zeros are displayed without leading zeros on the CYA page`(page: Page) { - val checkAnswersPage = - navigator.skipToPropertyRegistrationCheckAnswersPageOccupied( - households = 2, - people = 4, - bedrooms = 3, - rentAmount = "0000000.1", - ) - - assertThat(checkAnswersPage.summaryList.rentAmountRow.value).containsText("£0.1") - assertThat(checkAnswersPage.summaryList.numberOfHouseholdsRow.value).containsText("2") - assertThat(checkAnswersPage.summaryList.numberOfTenantsRow.value).containsText("4") - assertThat(checkAnswersPage.summaryList.numberOfBedroomsRow.value).containsText("3") - } - - @Test - fun `CYA joint landlords row shows a change link to the check joint landlords page when landlords are invited`(page: Page) { - val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPageWithJointLandlords() - - val changeLink = - checkAnswersPage.summaryList.jointLandlordsInvitationsRow.actions - .getActionLink("Change") - assertThat(changeLink).isVisible() - - changeLink.clickAndWait() - val checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordsPage.summaryList.firstRow.value).containsText("email@address.com") - } - - @Test - fun `CYA joint landlords row shows a change link to the has joint landlords page when there are no joint landlords`(page: Page) { - val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() - - val changeLink = - checkAnswersPage.summaryList.jointLandlordsAreThereRow.actions - .getActionLink("Change") - assertThat(changeLink).isVisible() - - changeLink.clickAndWait() - assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - } - - @Test - fun `a landlord cannot invite themselves as a joint landlord`(page: Page) { - val inviteJointLandlordPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - - inviteJointLandlordPage.submitEmail("alex.surname@example.com") - - val inviteJointLandlordPageWithError = assertPageIs(page, InviteJointLandlordFormPagePropertyRegistration::class) - assertThat(inviteJointLandlordPageWithError.form.getErrorMessage()) - .containsText("You cannot invite yourself as a joint landlord") - - inviteJointLandlordPageWithError.submitEmail("someone.else@example.com") - assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - } + @Test + fun `CYA joint landlords row shows a change link to the check joint landlords page when landlords are invited`(page: Page) { + val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPageWithJointLandlords() + + val changeLink = + checkAnswersPage.summaryList.jointLandlordsInvitationsRow.actions + .getActionLink("Change") + assertThat(changeLink).isVisible() + + changeLink.clickAndWait() + val checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordsPage.summaryList.firstRow.value).containsText("email@address.com") + } + + @Test + fun `CYA joint landlords row shows a change link to the has joint landlords page when there are no joint landlords`(page: Page) { + val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() + + val changeLink = + checkAnswersPage.summaryList.jointLandlordsAreThereRow.actions + .getActionLink("Change") + assertThat(changeLink).isVisible() + + changeLink.clickAndWait() + assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + } + + @Test + fun `a landlord cannot invite themselves as a joint landlord`(page: Page) { + val inviteJointLandlordPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + + inviteJointLandlordPage.submitEmail("alex.surname@example.com") + + val inviteJointLandlordPageWithError = assertPageIs(page, InviteJointLandlordFormPagePropertyRegistration::class) + assertThat(inviteJointLandlordPageWithError.form.getErrorMessage()) + .containsText("You cannot invite yourself as a joint landlord") + + inviteJointLandlordPageWithError.submitEmail("someone.else@example.com") + assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) } } diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationSinglePageTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationSinglePageTests.kt index 490c995cd0..3db22916fd 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationSinglePageTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationSinglePageTests.kt @@ -50,6 +50,7 @@ import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyReg import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.NumberOfPeopleFormPagePropertyRegistration import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.OccupancyFormPagePropertyRegistration import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.OwnershipTypeFormPagePropertyRegistration +import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.ProvideLicensingLaterFormPagePropertyRegistration import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.RemoveJointLandlordAreYouSureFormPagePropertyRegistration import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages.SelectiveLicenceFormPagePropertyRegistration import uk.gov.communities.prsdb.webapp.models.dataModels.AddressDataModel @@ -64,3134 +65,1601 @@ class PropertyRegistrationSinglePageTests : IntegrationTestWithImmutableData("da @MockitoSpyBean private lateinit var savedJourneyStateRepository: SavedJourneyStateRepository + @BeforeEach + fun disableRestructureFlag() { + // These tests exercise the legacy property registration task list, so disable the restructure flag + // which is enabled by default in the integration config. + featureFlagManager.disableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + } + @Nested - inner class RestructureAndSkippingEnabled { - @BeforeEach - fun enableRestructureAndSkippingFlag() { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + inner class TaskListStep { + @Test + fun `Completing preceding steps will show a task as not started and completed steps as complete`(page: Page) { + navigator.skipToPropertyRegistrationHasJointLandlordsPage() + val taskListPage = navigator.goToPropertyRegistrationTaskList() + assert(taskListPage.taskHasStatus("Property address", "Complete")) + assert(taskListPage.taskHasStatus("Property type", "Complete")) + assert(taskListPage.taskHasStatus("How you own the property", "Complete")) + assert(taskListPage.taskHasStatus("If the property has a license", "Complete")) + assert(taskListPage.taskHasStatus("Tenancy and rental information", "Complete")) + assert(taskListPage.taskHasStatus("Invite joint landlords", "Not started")) + assert(taskListPage.taskHasStatus("Gas safety certificate", "Cannot start yet")) + assert(taskListPage.taskHasStatus("Electrical safety certificate", "Cannot start yet")) + assert(taskListPage.taskHasStatus("Energy performance certificate (EPC)", "Cannot start yet")) + } + + @Test + fun `EPC task (starting with an internal step) shows as Not Started when the user is on the first step they see`(page: Page) { + navigator.skipToPropertyRegistrationHasEpcPage() + val taskListPage = navigator.goToPropertyRegistrationTaskList() + assert(taskListPage.taskHasStatus("Energy performance certificate (EPC)", "Not started")) + } + + @Test + fun `Completing first step of a task will show a task as in progress and completed steps as complete`(page: Page) { + navigator.skipToPropertyRegistrationRentFrequencyPage() + val taskListPage = navigator.goToPropertyRegistrationTaskList() + assert(taskListPage.taskHasStatus("Property address", "Complete")) + assert(taskListPage.taskHasStatus("Property type", "Complete")) + assert(taskListPage.taskHasStatus("How you own the property", "Complete")) + assert(taskListPage.taskHasStatus("If the property has a license", "Complete")) + assert(taskListPage.taskHasStatus("Tenancy and rental information", "In progress")) + assert(taskListPage.taskHasStatus("Invite joint landlords", "Cannot start yet")) + assert(taskListPage.taskHasStatus("Gas safety certificate", "Cannot start yet")) + assert(taskListPage.taskHasStatus("Electrical safety certificate", "Cannot start yet")) + assert(taskListPage.taskHasStatus("Energy performance certificate (EPC)", "Cannot start yet")) } + } - @Nested - inner class TaskListStep { - @Test - fun `Completing preceding steps will show a task as not started and completed steps as complete`(page: Page) { - navigator.skipToPropertyRegistrationHasJointLandlordsPage() - val taskListPage = navigator.goToPropertyRegistrationTaskList() - assert(taskListPage.getAboutYourPropertyTask("Property details").statusText.contains("Complete")) - assert(taskListPage.getAboutYourPropertyTask("Ownership and landlords").statusText.contains("In progress")) - assert(taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.contains("Cannot start yet")) - assert(taskListPage.getRentedOutTask("Tell us if your property needs a license").statusText.contains("Cannot start yet")) - assert(taskListPage.getRentedOutTask("Gas safety certificate").statusText.contains("Cannot start yet")) - assert(taskListPage.getRentedOutTask("Electrical safety certificate").statusText.contains("Cannot start yet")) - assert(taskListPage.getRentedOutTask("Energy performance certificate (EPC)").statusText.contains("Cannot start yet")) - assert(taskListPage.getRentedOutTask("Tenancy details").statusText.contains("Cannot start yet")) - assert(taskListPage.getSubmitYourRegistrationTask("Check and submit your answers").statusText.contains("Cannot start yet")) - } - - @Test - fun `EPC task (starting with an internal step) shows as Not Started when the user is on the first step they see`(page: Page) { - navigator.skipToPropertyRegistrationHasEpcPage() - val taskListPage = navigator.goToPropertyRegistrationTaskList() - assert(taskListPage.getRentedOutTask("Energy performance certificate (EPC)").statusText.contains("Not started")) - } - - @Test - fun `Completing first step of a task will show a task as in progress and completed steps as complete`(page: Page) { - navigator.skipToPropertyRegistrationHasGasCertPage() - val taskListPage = navigator.goToPropertyRegistrationTaskList() - assert(taskListPage.getAboutYourPropertyTask("Property details").statusText.contains("Complete")) - assert(taskListPage.getAboutYourPropertyTask("Ownership and landlords").statusText.contains("Complete")) - assert(taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.contains("Complete")) - assert(taskListPage.getRentedOutTask("Tell us if your property needs a license").statusText.contains("Complete")) - assert(taskListPage.getRentedOutTask("Gas safety certificate").statusText.contains("In progress")) - assert(taskListPage.getRentedOutTask("Electrical safety certificate").statusText.contains("Cannot start yet")) - assert(taskListPage.getRentedOutTask("Energy performance certificate (EPC)").statusText.contains("Cannot start yet")) - assert(taskListPage.getRentedOutTask("Tenancy details").statusText.contains("Cannot start yet")) - assert(taskListPage.getSubmitYourRegistrationTask("Check and submit your answers").statusText.contains("Cannot start yet")) - } + @Nested + inner class LookupAddressAndNoAddressFoundSteps { + @Test + fun `Submitting with empty data fields returns an error`(page: Page) { + val lookupAddressPage = navigator.goToPropertyRegistrationLookupAddressPage() + lookupAddressPage.clearForm() // There may be form answers in the journey state + lookupAddressPage.form.submit() + assertThat(lookupAddressPage.form.getErrorMessage("postcode")).containsText("Enter a postcode") + assertThat(lookupAddressPage.form.getErrorMessage("houseNameOrNumber")).containsText("Enter a house name or number") + } + + @Test + fun `If no English addresses are found, user can search again or enter address manually via the No Address Found step`(page: Page) { + // Lookup address finds no English results + val houseNumber = "NOT A HOUSE NUMBER" + val postcode = "NOT A POSTCODE" + var lookupAddressPage = navigator.goToPropertyRegistrationLookupAddressPage() + lookupAddressPage.submitPostcodeAndBuildingNameOrNumber(postcode, houseNumber) + + // redirect to noAddressFoundPage + var noAddressFoundPage = assertPageIs(page, NoAddressFoundFormPagePropertyRegistration::class) + BaseComponent + .assertThat(noAddressFoundPage.heading) + .containsText("No matching address in England found for $postcode and $houseNumber") + + // Search Again + noAddressFoundPage.searchAgain.clickAndWait() + lookupAddressPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + lookupAddressPage.submitPostcodeAndBuildingNameOrNumber(postcode, houseNumber) + + // Submit no address found page + noAddressFoundPage = assertPageIs(page, NoAddressFoundFormPagePropertyRegistration::class) + noAddressFoundPage.form.submit() + assertPageIs(page, ManualAddressFormPagePropertyRegistration::class) } + } - @Nested - inner class LookupAddressAndNoAddressFoundSteps { - @Test - fun `Submitting with empty data fields returns an error`(page: Page) { - val lookupAddressPage = navigator.goToPropertyRegistrationLookupAddressPage() - lookupAddressPage.clearForm() // There may be form answers in the journey state - lookupAddressPage.form.submit() - assertThat(lookupAddressPage.form.getErrorMessage("postcode")).containsText("Enter a postcode") - assertThat(lookupAddressPage.form.getErrorMessage("houseNameOrNumber")).containsText("Enter a house name or number") - } - - @Test - fun `If no English addresses are found, user can search again or enter address manually via the No Address Found step`( - page: Page, - ) { - // Lookup address finds no English results - val houseNumber = "NOT A HOUSE NUMBER" - val postcode = "NOT A POSTCODE" - var lookupAddressPage = navigator.goToPropertyRegistrationLookupAddressPage() - lookupAddressPage.submitPostcodeAndBuildingNameOrNumber(postcode, houseNumber) - - // redirect to noAddressFoundPage - var noAddressFoundPage = assertPageIs(page, NoAddressFoundFormPagePropertyRegistration::class) - BaseComponent - .assertThat(noAddressFoundPage.heading) - .containsText("No matching address in England found for $postcode and $houseNumber") - - // Search Again - noAddressFoundPage.searchAgain.clickAndWait() - lookupAddressPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - lookupAddressPage.submitPostcodeAndBuildingNameOrNumber(postcode, houseNumber) - - // Submit no address found page - noAddressFoundPage = assertPageIs(page, NoAddressFoundFormPagePropertyRegistration::class) - noAddressFoundPage.form.submit() - assertPageIs(page, ManualAddressFormPagePropertyRegistration::class) - } + @Nested + inner class SelectAddressStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage() + selectAddressPage.form.submit() + assertThat(selectAddressPage.form.getErrorMessage()).containsText("Select an address") } - @Nested - inner class SelectAddressStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage() - selectAddressPage.form.submit() - assertThat(selectAddressPage.form.getErrorMessage()).containsText("Select an address") - } - - @Test - fun `Clicking Search Again navigates to the previous step`(page: Page) { - val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage() - selectAddressPage.searchAgain.clickAndWait() - assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - } - - @Test - fun `Selecting an already-registered address navigates to the AlreadyRegistered step`(page: Page) { - val alreadyRegisteredAddress = AddressDataModel("1 Example Road", uprn = 1123456) - val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage(listOf(alreadyRegisteredAddress)) - selectAddressPage.selectAddressAndSubmit(alreadyRegisteredAddress.singleLineAddress) - assertPageIs(page, AlreadyRegisteredFormPagePropertyRegistration::class) - } + @Test + fun `Clicking Search Again navigates to the previous step`(page: Page) { + val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage() + selectAddressPage.searchAgain.clickAndWait() + assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) } - @Nested - inner class ManualAddressEntryStep { - @Test - fun `Submitting empty data fields returns errors`(page: Page) { - val manualAddressPage = navigator.skipToPropertyRegistrationManualAddressPage() - manualAddressPage.submitAddress() - assertThat(manualAddressPage.form.getErrorMessage("addressLineOne")) - .containsText("Enter the first line of an address, typically the building and street") - assertThat(manualAddressPage.form.getErrorMessage("townOrCity")).containsText("Enter town or city") - assertThat(manualAddressPage.form.getErrorMessage("postcode")).containsText("Enter postcode") - } + @Test + fun `Selecting an already-registered address navigates to the AlreadyRegistered step`(page: Page) { + val alreadyRegisteredAddress = AddressDataModel("1 Example Road", uprn = 1123456) + val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage(listOf(alreadyRegisteredAddress)) + selectAddressPage.selectAddressAndSubmit(alreadyRegisteredAddress.singleLineAddress) + assertPageIs(page, AlreadyRegisteredFormPagePropertyRegistration::class) } + } - @Nested - inner class SelectLocalCouncilStep { - @Test - fun `Submitting without selecting an LA return an error`(page: Page) { - val selectLocalCouncilPage = navigator.skipToPropertyRegistrationSelectLocalCouncilPage() - selectLocalCouncilPage.form.submit() - assertThat(selectLocalCouncilPage.form.getErrorMessage("localCouncilId")) - .containsText("Select a local council to continue") - } + @Nested + inner class ManualAddressEntryStep { + @Test + fun `Submitting empty data fields returns errors`(page: Page) { + val manualAddressPage = navigator.skipToPropertyRegistrationManualAddressPage() + manualAddressPage.submitAddress() + assertThat(manualAddressPage.form.getErrorMessage("addressLineOne")) + .containsText("Enter the first line of an address, typically the building and street") + assertThat(manualAddressPage.form.getErrorMessage("townOrCity")).containsText("Enter town or city") + assertThat(manualAddressPage.form.getErrorMessage("postcode")).containsText("Enter postcode") } + } - @Nested - inner class PropertyTypeStep { - @Test - fun `Submitting with no propertyType selected returns an error`(page: Page) { - val propertyTypePage = navigator.skipToPropertyRegistrationPropertyTypePage() - propertyTypePage.form.submit() - assertThat(propertyTypePage.form.getErrorMessage()).containsText("Select the type of property") - } + @Nested + inner class SelectLocalCouncilStep { + @Test + fun `Submitting without selecting an LA return an error`(page: Page) { + val selectLocalCouncilPage = navigator.skipToPropertyRegistrationSelectLocalCouncilPage() + selectLocalCouncilPage.form.submit() + assertThat(selectLocalCouncilPage.form.getErrorMessage("localCouncilId")) + .containsText("Select a local council to continue") + } + } - @Test - fun `Submitting with the Other propertyType selected but an empty customPropertyType field returns an error`(page: Page) { - val propertyTypePage = navigator.skipToPropertyRegistrationPropertyTypePage() - propertyTypePage.submitCustomPropertyType("") - assertThat(propertyTypePage.form.getErrorMessage()).containsText("Enter the property type") - } + @Nested + inner class PropertyTypeStep { + @Test + fun `Submitting with no propertyType selected returns an error`(page: Page) { + val propertyTypePage = navigator.skipToPropertyRegistrationPropertyTypePage() + propertyTypePage.form.submit() + assertThat(propertyTypePage.form.getErrorMessage()).containsText("Select the type of property") } - @Nested - inner class OwnershipTypeStep { - @Test - fun `Submitting with no ownershipType selected returns an error`(page: Page) { - val ownershipTypePage = navigator.skipToPropertyRegistrationOwnershipTypePage() - ownershipTypePage.form.submit() - assertThat(ownershipTypePage.form.getErrorMessage()).containsText("Select the ownership type") - } + @Test + fun `Submitting with the Other propertyType selected but an empty customPropertyType field returns an error`(page: Page) { + val propertyTypePage = navigator.skipToPropertyRegistrationPropertyTypePage() + propertyTypePage.submitCustomPropertyType("") + assertThat(propertyTypePage.form.getErrorMessage()).containsText("Enter the property type") } + } - @Nested - inner class LicensingTypeStep { - @Test - fun `Submitting with no licensingType selected returns an error`(page: Page) { - val licensingTypePage = navigator.skipToPropertyRegistrationOccupiedLicensingTypePage() - licensingTypePage.form.submit() - assertThat(licensingTypePage.form.getErrorMessage()).containsText("Select the type of licensing for the property") - } + @Nested + inner class OwnershipTypeStep { + @Test + fun `Submitting with no ownershipType selected returns an error`(page: Page) { + val ownershipTypePage = navigator.skipToPropertyRegistrationOwnershipTypePage() + ownershipTypePage.form.submit() + assertThat(ownershipTypePage.form.getErrorMessage()).containsText("Select the ownership type") + } + } - @Test - fun `Submitting with an HMO mandatory licence redirects to the next step`(page: Page) { - val licensingTypePage = navigator.skipToPropertyRegistrationOccupiedLicensingTypePage() - licensingTypePage.submitLicensingType(LicensingType.HMO_MANDATORY_LICENCE) - val licenseNumberPage = assertPageIs(page, HmoMandatoryLicenceFormPagePropertyRegistration::class) - BaseComponent - .assertThat(licenseNumberPage.form.sectionHeader) - .containsText("Tell us if your property needs a license") - } + @Nested + inner class LicensingTypeStep { + @Test + fun `Submitting with no licensingType selected returns an error`(page: Page) { + val licensingTypePage = navigator.skipToPropertyRegistrationLicensingTypePage() + licensingTypePage.form.submit() + assertThat(licensingTypePage.form.getErrorMessage()).containsText("Select the type of licensing for the property") + } + + @Test + fun `Submitting with an HMO mandatory licence redirects to the next step`(page: Page) { + val licensingTypePage = navigator.skipToPropertyRegistrationLicensingTypePage() + licensingTypePage.submitLicensingType(LicensingType.HMO_MANDATORY_LICENCE) + val licenseNumberPage = assertPageIs(page, HmoMandatoryLicenceFormPagePropertyRegistration::class) + BaseComponent + .assertThat(licenseNumberPage.form.sectionHeader) + .containsText("Section 1 of 2 — Add property details") + } + + @Test + fun `Submitting with an HMO additional licence redirects to the next step`(page: Page) { + val licensingTypePage = navigator.skipToPropertyRegistrationLicensingTypePage() + licensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) + val licenseNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyRegistration::class) + BaseComponent + .assertThat(licenseNumberPage.form.sectionHeader) + .containsText("Section 1 of 2 — Add property details") + } + + @Test + fun `Submitting provide this later on licensing routes to occupied provide licensing later page`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - @Test - fun `Submitting with an HMO additional licence redirects to the next step`(page: Page) { - val licensingTypePage = navigator.skipToPropertyRegistrationOccupiedLicensingTypePage() - licensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) - val licenseNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyRegistration::class) - BaseComponent - .assertThat(licenseNumberPage.form.sectionHeader) - .containsText("Tell us if your property needs a license") - } - } + val taskListPage = + navigator.goToRestructuredPropertyRegistrationTaskList( + PropertyStateSessionBuilder + .beforePropertyRegistrationOwnershipType() + .withBedrooms() + .withOwnershipType() + .withHasNoJointLandlords() + .withOccupancyStatus(true), + ) + taskListPage.clickRentedOutTaskWithName("Tell us if your property needs a license") + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + assertThat(licensingTypePage.provideThisLaterButton).isVisible() - @Nested - inner class SelectiveLicenceStep { - @Test - fun `Submitting with no licence number returns an error`(page: Page) { - val selectiveLicencePage = navigator.skipToPropertyRegistrationOccupiedSelectiveLicencePage() - selectiveLicencePage.form.submit() - assertThat(selectiveLicencePage.form.getErrorMessage()).containsText("Enter the selective licence number") - } + licensingTypePage.submitProvideThisLater() + val provideLicensingLaterPage = assertPageIs(page, ProvideLicensingLaterFormPagePropertyRegistration::class) - @Test - fun `Submitting with a very long licence number returns an error`(page: Page) { - val selectiveLicencePage = navigator.skipToPropertyRegistrationOccupiedSelectiveLicencePage() - val aVeryLongString = - "This string is very long, so long that it is not feasible that it is a real licence number " + - "- therefore if it is submitted there will in fact be an error rather than a successful submission." + - " It is actually quite difficult for a string to be long enough to trigger this error, because the" + - " maximum length has been selected to be permissive of id numbers we do not expect while still having " + - "a cap reachable with a little effort." - selectiveLicencePage.submitLicenseNumber(aVeryLongString) - assertThat(selectiveLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") - } + BaseComponent + .assertThat(provideLicensingLaterPage.heading) + .containsText("Provide details about property licensing later") + BaseComponent.assertThat(provideLicensingLaterPage.insetText).isVisible() } - @Nested - inner class HmoMandatoryLicenceStep { - @Test - fun `Submitting with a licence number redirects to the next step`(page: Page) { - val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationOccupiedHmoMandatoryLicencePage() - hmoMandatoryLicencePage.submitLicenseNumber("licence number") - assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - } + @Test + fun `Submitting provide this later on licensing routes to unoccupied provide licensing later page`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - @Test - fun `Submitting with no licence number returns an error`(page: Page) { - val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationOccupiedHmoMandatoryLicencePage() - hmoMandatoryLicencePage.form.submit() - assertThat(hmoMandatoryLicencePage.form.getErrorMessage()).containsText("Enter the HMO Mandatory licence number") - } + val taskListPage = + navigator.goToRestructuredPropertyRegistrationTaskList( + PropertyStateSessionBuilder + .beforePropertyRegistrationOwnershipType() + .withBedrooms() + .withOwnershipType() + .withHasNoJointLandlords() + .withOccupancyStatus(false), + ) + taskListPage.clickRentedOutTaskWithName("Tell us if your property needs a license") + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + assertThat(licensingTypePage.provideThisLaterButton).isVisible() - @Test - fun `Submitting with a very long licence number returns an error`(page: Page) { - val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationOccupiedHmoMandatoryLicencePage() - val aVeryLongString = - "This string is very long, so long that it is not feasible that it is a real licence number " + - "- therefore if it is submitted there will in fact be an error rather than a successful submission." + - " It is actually quite difficult for a string to be long enough to trigger this error, because the" + - " maximum length has been selected to be permissive of id numbers we do not expect while still having " + - "a cap reachable with a little effort." - hmoMandatoryLicencePage.submitLicenseNumber(aVeryLongString) - assertThat(hmoMandatoryLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") - } + licensingTypePage.submitProvideThisLater() + val provideLicensingLaterPage = assertPageIs(page, ProvideLicensingLaterFormPagePropertyRegistration::class) + + BaseComponent + .assertThat(provideLicensingLaterPage.heading) + .containsText("Provide details about property licensing later") + BaseComponent.assertThat(provideLicensingLaterPage.insetText).isHidden() } + } - @Nested - inner class HmoAdditionalLicenceStep { - @Test - fun `Submitting with a licence number redirects to the next step`(page: Page) { - val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationOccupiedHmoAdditionalLicencePage() - hmoAdditionalLicencePage.submitLicenseNumber("licence number") - assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - } + @Nested + inner class SelectiveLicenceStep { + @Test + fun `Submitting with no licence number returns an error`(page: Page) { + val selectiveLicencePage = navigator.skipToPropertyRegistrationSelectiveLicencePage() + selectiveLicencePage.form.submit() + assertThat(selectiveLicencePage.form.getErrorMessage()).containsText("Enter the selective licence number") + } + + @Test + fun `Submitting with a very long licence number returns an error`(page: Page) { + val selectiveLicencePage = navigator.skipToPropertyRegistrationSelectiveLicencePage() + val aVeryLongString = + "This string is very long, so long that it is not feasible that it is a real licence number " + + "- therefore if it is submitted there will in fact be an error rather than a successful submission." + + " It is actually quite difficult for a string to be long enough to trigger this error, because the" + + " maximum length has been selected to be permissive of id numbers we do not expect while still having " + + "a cap reachable with a little effort." + selectiveLicencePage.submitLicenseNumber(aVeryLongString) + assertThat(selectiveLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") + } + } - @Test - fun `Submitting with no licence number returns an error`(page: Page) { - val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationOccupiedHmoAdditionalLicencePage() - hmoAdditionalLicencePage.form.submit() - assertThat(hmoAdditionalLicencePage.form.getErrorMessage()).containsText("Enter the HMO additional licence number") - } + @Nested + inner class HmoMandatoryLicenceStep { + @Test + fun `Submitting with a licence number redirects to the next step`(page: Page) { + val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationHmoMandatoryLicencePage() + hmoMandatoryLicencePage.submitLicenseNumber("licence number") + assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + } + + @Test + fun `Submitting with no licence number returns an error`(page: Page) { + val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationHmoMandatoryLicencePage() + hmoMandatoryLicencePage.form.submit() + assertThat(hmoMandatoryLicencePage.form.getErrorMessage()).containsText("Enter the HMO Mandatory licence number") + } + + @Test + fun `Submitting with a very long licence number returns an error`(page: Page) { + val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationHmoMandatoryLicencePage() + val aVeryLongString = + "This string is very long, so long that it is not feasible that it is a real licence number " + + "- therefore if it is submitted there will in fact be an error rather than a successful submission." + + " It is actually quite difficult for a string to be long enough to trigger this error, because the" + + " maximum length has been selected to be permissive of id numbers we do not expect while still having " + + "a cap reachable with a little effort." + hmoMandatoryLicencePage.submitLicenseNumber(aVeryLongString) + assertThat(hmoMandatoryLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") + } + } - @Test - fun `Submitting with a very long licence number returns an error`(page: Page) { - val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationOccupiedHmoAdditionalLicencePage() - val aVeryLongString = - "This string is very long, so long that it is not feasible that it is a real licence number " + - "- therefore if it is submitted there will in fact be an error rather than a successful submission." + - " It is actually quite difficult for a string to be long enough to trigger this error, because the" + - " maximum length has been selected to be permissive of id numbers we do not expect while still having " + - "a cap reachable with a little effort." - hmoAdditionalLicencePage.submitLicenseNumber(aVeryLongString) - assertThat(hmoAdditionalLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") - } + @Nested + inner class HmoAdditionalLicenceStep { + @Test + fun `Submitting with a licence number redirects to the next step`(page: Page) { + val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationHmoAdditionalLicencePage() + hmoAdditionalLicencePage.submitLicenseNumber("licence number") + assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + } + + @Test + fun `Submitting with no licence number returns an error`(page: Page) { + val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationHmoAdditionalLicencePage() + hmoAdditionalLicencePage.form.submit() + assertThat(hmoAdditionalLicencePage.form.getErrorMessage()).containsText("Enter the HMO additional licence number") + } + + @Test + fun `Submitting with a very long licence number returns an error`(page: Page) { + val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationHmoAdditionalLicencePage() + val aVeryLongString = + "This string is very long, so long that it is not feasible that it is a real licence number " + + "- therefore if it is submitted there will in fact be an error rather than a successful submission." + + " It is actually quite difficult for a string to be long enough to trigger this error, because the" + + " maximum length has been selected to be permissive of id numbers we do not expect while still having " + + "a cap reachable with a little effort." + hmoAdditionalLicencePage.submitLicenseNumber(aVeryLongString) + assertThat(hmoAdditionalLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") } + } - @Nested - inner class OccupancyStep { - @Test - fun `Submitting with no occupancy option selected returns an error`(page: Page) { - val occupancyPage = navigator.skipToPropertyRegistrationRestructuredOccupancyPage() - occupancyPage.form.submit() - assertThat(occupancyPage.form.getErrorMessage()).containsText("Select whether the property is occupied") - } + @Nested + inner class OccupancyStep { + @Test + fun `Submitting with no occupancy option selected returns an error`(page: Page) { + val occupancyPage = navigator.skipToPropertyRegistrationOccupancyPage() + occupancyPage.form.submit() + assertThat(occupancyPage.form.getErrorMessage()).containsText("Select whether the property is occupied") } + } - @Nested - inner class NumberOfHouseholdsStep { - @Test - fun `Submitting with a blank numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToTenancyDetailsHouseholdsPage() - householdsPage.form.submit() - assertThat(householdsPage.form.getErrorMessage()).containsText("Enter how many separate households, like 1 or 2") - } + @Nested + inner class NumberOfHouseholdsStep { + @Test + fun `Submitting with a blank numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() + householdsPage.form.submit() + assertThat(householdsPage.form.getErrorMessage()).containsText("Enter how many separate households, like 1 or 2") + } - @Test - fun `Submitting with a non-numerical value in the numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToTenancyDetailsHouseholdsPage() - householdsPage.submitNumberOfHouseholds("not-a-number") - assertThat(householdsPage.form.getErrorMessage()) - .containsText("Enter how many separate households, like 1 or 2") - } + @Test + fun `Submitting with a non-numerical value in the numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() + householdsPage.submitNumberOfHouseholds("not-a-number") + assertThat(householdsPage.form.getErrorMessage()) + .containsText("Enter how many separate households, like 1 or 2") + } - @Test - fun `Submitting with a non-integer number in the numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToTenancyDetailsHouseholdsPage() - householdsPage.submitNumberOfHouseholds("2.3") - assertThat(householdsPage.form.getErrorMessage()) - .containsText("Enter how many separate households, like 1 or 2") - } + @Test + fun `Submitting with a non-integer number in the numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() + householdsPage.submitNumberOfHouseholds("2.3") + assertThat(householdsPage.form.getErrorMessage()) + .containsText("Enter how many separate households, like 1 or 2") + } - @Test - fun `Submitting with a negative integer in the numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToTenancyDetailsHouseholdsPage() - householdsPage.submitNumberOfHouseholds(-2) - assertThat(householdsPage.form.getErrorMessage()) - .containsText("Enter how many separate households, like 1 or 2") - } + @Test + fun `Submitting with a negative integer in the numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() + householdsPage.submitNumberOfHouseholds(-2) + assertThat(householdsPage.form.getErrorMessage()) + .containsText("Enter how many separate households, like 1 or 2") + } - @Test - fun `Submitting with a zero integer in the numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToTenancyDetailsHouseholdsPage() - householdsPage.submitNumberOfHouseholds(0) - assertThat(householdsPage.form.getErrorMessage()) - .containsText("Enter how many separate households, like 1 or 2") - } + @Test + fun `Submitting with a zero integer in the numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() + householdsPage.submitNumberOfHouseholds(0) + assertThat(householdsPage.form.getErrorMessage()) + .containsText("Enter how many separate households, like 1 or 2") } + } - @Nested - inner class NumberOfPeopleStep { - @Test - fun `Submitting with a blank numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToTenancyDetailsPeoplePage() - peoplePage.form.submit() - assertThat(peoplePage.form.getErrorMessage()).containsText("Enter how many people, like 2 or 5") - } + @Nested + inner class NumberOfPeopleStep { + @Test + fun `Submitting with a blank numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() + peoplePage.form.submit() + assertThat(peoplePage.form.getErrorMessage()).containsText("Enter how many people, like 2 or 5") + } + + @Test + fun `Submitting with a non-numerical value in the numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() + peoplePage.submitNumOfPeople("not-a-number") + assertThat(peoplePage.form.getErrorMessage()) + .containsText("Enter how many people, like 2 or 5") + } + + @Test + fun `Submitting with a non-integer number in the numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() + peoplePage.submitNumOfPeople("2.3") + assertThat(peoplePage.form.getErrorMessage()) + .containsText("Enter how many people, like 2 or 5") + } + + @Test + fun `Submitting with a negative integer in the numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() + peoplePage.submitNumOfPeople("-2") + assertThat(peoplePage.form.getErrorMessage()) + .containsText("Enter how many people, like 2 or 5") + } + + @Test + fun `Submitting with a zero integer in the numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() + peoplePage.submitNumOfPeople(0) + assertThat(peoplePage.form.getErrorMessage()) + .containsText("Enter how many people, like 2 or 5") + } + + @Test + fun `Submitting with an integer in the numberOfPeople field that is less than the numberOfHouseholds returns an error`( + page: Page, + ) { + val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() + householdsPage.submitNumberOfHouseholds(3) + val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) + peoplePage.submitNumOfPeople(2) + assertThat(peoplePage.form.getErrorMessage()) + .containsText( + "The number of people in the property must be the same as or higher than the number of households in the property", + ) + } + } - @Test - fun `Submitting with a non-numerical value in the numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToTenancyDetailsPeoplePage() - peoplePage.submitNumOfPeople("not-a-number") - assertThat(peoplePage.form.getErrorMessage()) - .containsText("Enter how many people, like 2 or 5") - } + @Nested + inner class NumberOfBedroomsStep { + val numberOfBedroomsErrorMessage = "Enter the number of bedrooms, like 3 or 8" - @Test - fun `Submitting with a non-integer number in the numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToTenancyDetailsPeoplePage() - peoplePage.submitNumOfPeople("2.3") - assertThat(peoplePage.form.getErrorMessage()) - .containsText("Enter how many people, like 2 or 5") - } + @Test + fun `Submitting with a blank numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.form.submit() + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) + } - @Test - fun `Submitting with a negative integer in the numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToTenancyDetailsPeoplePage() - peoplePage.submitNumOfPeople("-2") - assertThat(peoplePage.form.getErrorMessage()) - .containsText("Enter how many people, like 2 or 5") - } + @Test + fun `Submitting with a non-numerical value in the numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.submitNumOfBedrooms("not-a-number") + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) + } - @Test - fun `Submitting with a zero integer in the numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToTenancyDetailsPeoplePage() - peoplePage.submitNumOfPeople(0) - assertThat(peoplePage.form.getErrorMessage()) - .containsText("Enter how many people, like 2 or 5") - } + @Test + fun `Submitting with a non-integer number in the numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.submitNumOfBedrooms("2.3") + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) + } - @Test - fun `Submitting with an integer in the numberOfPeople field that is less than the numberOfHouseholds returns an error`( - page: Page, - ) { - val householdsPage = navigator.skipToTenancyDetailsHouseholdsPage() - householdsPage.submitNumberOfHouseholds(3) - val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) - peoplePage.submitNumOfPeople(2) - assertThat(peoplePage.form.getErrorMessage()) - .containsText( - "The number of people in the property must be the same as or higher than the number of households in the property", - ) - } + @Test + fun `Submitting with a negative integer in the numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.submitNumOfBedrooms("-2") + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) } - @Nested - inner class NumberOfBedroomsStep { - val numberOfBedroomsErrorMessage = "Enter the number of bedrooms, like 3 or 8" + @Test + fun `Submitting with a zero integer in the numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.submitNumOfBedrooms(0) + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) + } + } - @Test - fun `Submitting with a blank numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.form.submit() - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } + @Nested + inner class RentIncludesBillsStep { + @Test + fun `Submitting with no rent included option selected returns an error`(page: Page) { + val rentIncludesBillsPage = navigator.skipToPropertyRegistrationRentIncludesBillsPage() + rentIncludesBillsPage.form.submit() + assertThat(rentIncludesBillsPage.form.getErrorMessage()).containsText("Select whether the rent includes bills") + } + } - @Test - fun `Submitting with a non-numerical value in the numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.submitNumOfBedrooms("not-a-number") - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } + @Nested + inner class BillsIncludedStep { + @Test + fun `Submitting with no bills included selected returns an error`(page: Page) { + val billsIncludedPage = navigator.skipToPropertyRegistrationBillsIncludedPage() + billsIncludedPage.form.submit() + assertThat(billsIncludedPage.form.getErrorMessage()).containsText("Select what you include in the rent") + } + + @Test + fun `Submitting with something else selected but no text entered returns an error`(page: Page) { + val billsIncludedPage = navigator.skipToPropertyRegistrationBillsIncludedPage() + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.selectSomethingElseCheckbox() + billsIncludedPage.form.submit() + assertThat(billsIncludedPage.form.getErrorMessage()).containsText("Enter the bills and services you include in the rent") + } + + @Test + fun `Submitting with a very long something else text returns an error`(page: Page) { + val billsIncludedPage = navigator.skipToPropertyRegistrationBillsIncludedPage() + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.selectSomethingElseCheckbox() + val aVeryLongString = + "This string is very long, so long that it is not feasible that it is a real description " + + "- therefore if it is submitted there will in fact be an error rather than a successful submission." + + " It is actually quite difficult for a string to be long enough to trigger this error, because the" + + " maximum length has been selected to be permissive of descriptions we do not expect while still having " + + "a cap reachable with a little effort." + billsIncludedPage.fillCustomBills(aVeryLongString) + billsIncludedPage.form.submit() + assertThat(billsIncludedPage.form.getErrorMessage("customBillsIncluded")) + .containsText("The description of other bills and services must be 200 characters or fewer") + } + } - @Test - fun `Submitting with a non-integer number in the numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.submitNumOfBedrooms("2.3") - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } + @Nested + inner class FurnishedStatusStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val furnishedStatusPage = navigator.skipToPropertyRegistrationFurnishedStatusPage() + furnishedStatusPage.form.submit() + assertThat( + furnishedStatusPage.form.getErrorMessage(), + ).containsText("Select whether the property is furnished, partly furnished or unfurnished") + } + } - @Test - fun `Submitting with a negative integer in the numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.submitNumOfBedrooms("-2") - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } + @Nested + inner class RentFrequencyStep { + @Test + fun `Submitting with no rentFrequency selected returns an error`(page: Page) { + val rentFrequencyPage = navigator.skipToPropertyRegistrationRentFrequencyPage() + rentFrequencyPage.form.submit() + assertThat(rentFrequencyPage.form.getErrorMessage()).containsText("Select how often you charge rent") + } - @Test - fun `Submitting with a zero integer in the numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.submitNumOfBedrooms(0) - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } + @Test + fun `Submitting with other rent frequency selected but no text entered returns an error`(page: Page) { + val rentFrequencyPage = navigator.skipToPropertyRegistrationRentFrequencyPage() + rentFrequencyPage.selectRentFrequency(RentFrequency.OTHER) + rentFrequencyPage.form.submit() + assertThat(rentFrequencyPage.form.getErrorMessage()).containsText("Enter how often you charge rent") } + } - @Nested - inner class RentIncludesBillsStep { - @Test - fun `Submitting with no rent included option selected returns an error`(page: Page) { - val rentIncludesBillsPage = navigator.skipToTenancyDetailsRentIncludesBillsPage() - rentIncludesBillsPage.form.submit() - assertThat(rentIncludesBillsPage.form.getErrorMessage()).containsText("Select whether the rent includes bills") - } + @Nested + inner class RentAmountStep { + @Test + fun `Submitting no rentAmount returns an error`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() + rentAmountPage.form.submit() + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") } - @Nested - inner class BillsIncludedStep { - @Test - fun `Submitting with no bills included selected returns an error`() { - val billsIncludedPage = navigator.skipToTenancyDetailsBillsIncludedPage() - billsIncludedPage.form.submit() - assertThat(billsIncludedPage.form.getErrorMessage()).containsText("Select what you include in the rent") - } + @Test + fun `Submitting a rentAmount greater than two decimals returns an error`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() + rentAmountPage.submitRentAmount("400.123") + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + } - @Test - fun `Submitting with something else selected but no text entered returns an error`() { - val billsIncludedPage = navigator.skipToTenancyDetailsBillsIncludedPage() - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.selectSomethingElseCheckbox() - billsIncludedPage.form.submit() - assertThat(billsIncludedPage.form.getErrorMessage()).containsText("Enter the bills and services you include in the rent") - } + @Test + fun `Submitting a negative rentAmount returns an error`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() + rentAmountPage.submitRentAmount("-400.12") + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + } - @Test - fun `Submitting with a very long something else text returns an error`() { - val billsIncludedPage = navigator.skipToTenancyDetailsBillsIncludedPage() - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.selectSomethingElseCheckbox() - val aVeryLongString = - "This string is very long, so long that it is not feasible that it is a real description " + - "- therefore if it is submitted there will in fact be an error rather than a successful submission." + - " It is actually quite difficult for a string to be long enough to trigger this error, because the" + - " maximum length has been selected to be permissive of descriptions we do not expect while still having " + - "a cap reachable with a little effort." - billsIncludedPage.fillCustomBills(aVeryLongString) - billsIncludedPage.form.submit() - assertThat(billsIncludedPage.form.getErrorMessage("customBillsIncluded")) - .containsText("The description of other bills and services must be 200 characters or fewer") - } + @Test + fun `Submitting a non-numerical rentAmount returns an error`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() + rentAmountPage.submitRentAmount("not-a-number") + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") } - @Nested - inner class FurnishedStatusStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val furnishedStatusPage = navigator.skipToTenancyDetailsFurnishedStatusPage() - furnishedStatusPage.form.submit() - assertThat( - furnishedStatusPage.form.getErrorMessage(), - ).containsText("Select whether the property is furnished, partly furnished or unfurnished") - } + @Test + fun `Submitting a rentAmount of 10000000 or above returns an error`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() + rentAmountPage.submitRentAmount("10000000") + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") } @Nested - inner class RentFrequencyStep { + inner class ConditionalContentPerRentFrequency { @Test - fun `Submitting with no rentFrequency selected returns an error`() { - val rentFrequencyPage = navigator.skipToTenancyDetailsRentFrequencyPage() - rentFrequencyPage.form.submit() - assertThat(rentFrequencyPage.form.getErrorMessage()).containsText("Select how often you charge rent") + fun `Page renders correctly for weekly rent frequency`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.WEEKLY) + BaseComponent + .assertThat(rentAmountPage.header) + .containsText("What is the weekly rent?") + BaseComponent + .assertThat(rentAmountPage.subheading) + .containsText("Weekly rent") + BaseComponent + .assertThat(rentAmountPage.billsExplanationForRentFrequency) + .containsText("The amount you enter must be the total weekly rent agreed with the tenant.") + BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() } @Test - fun `Submitting with other rent frequency selected but no text entered returns an error`() { - val rentFrequencyPage = navigator.skipToTenancyDetailsRentFrequencyPage() - rentFrequencyPage.selectRentFrequency(RentFrequency.OTHER) - rentFrequencyPage.form.submit() - assertThat(rentFrequencyPage.form.getErrorMessage()).containsText("Enter how often you charge rent") + fun `Page renders correctly for four weekly rent frequency`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.FOUR_WEEKLY) + BaseComponent + .assertThat(rentAmountPage.header) + .containsText("What is the 4-weekly rent?") + BaseComponent + .assertThat(rentAmountPage.subheading) + .containsText("4-weekly rent") + BaseComponent + .assertThat(rentAmountPage.billsExplanationForRentFrequency) + .containsText("The amount you enter must be the total 4-weekly rent agreed with the tenant.") + BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() } - } - @Nested - inner class RentAmountStep { @Test - fun `Submitting no rentAmount returns an error`(page: Page) { - val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage() - rentAmountPage.form.submit() - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + fun `Page renders correctly for monthly rent frequency`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.MONTHLY) + BaseComponent + .assertThat(rentAmountPage.header) + .containsText("What is the monthly rent?") + BaseComponent + .assertThat(rentAmountPage.subheading) + .containsText("Monthly rent") + BaseComponent + .assertThat(rentAmountPage.billsExplanationForRentFrequency) + .containsText("The amount you enter must be the total monthly rent agreed with the tenant.") + BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() } @Test - fun `Submitting a rentAmount greater than two decimals returns an error`(page: Page) { - val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage() - rentAmountPage.submitRentAmount("400.123") - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + fun `Page renders correctly for 'other' rent frequency`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.OTHER) + BaseComponent + .assertThat(rentAmountPage.header) + .containsText("What is the monthly rent?") + BaseComponent + .assertThat(rentAmountPage.subheading) + .containsText("Monthly rent") + BaseComponent + .assertThat(rentAmountPage.billsExplanationForRentFrequency) + .containsText("The amount you enter must be the total monthly rent agreed with the tenant.") + BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isVisible() } + } + } - @Test - fun `Submitting a negative rentAmount returns an error`(page: Page) { - val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage() - rentAmountPage.submitRentAmount("-400.12") - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") - } + @Nested + inner class HasJointLandlordsStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val hasJointLandlordsPage = navigator.skipToPropertyRegistrationHasJointLandlordsPage() + hasJointLandlordsPage.form.submit() + assertThat(hasJointLandlordsPage.form.getErrorMessage()) + .containsText("Select if there are any other landlords for this property") + } + + @Test + fun `The link renders correctly`(page: Page) { + val hasJointLandlordsPage = navigator.skipToPropertyRegistrationHasJointLandlordsPage() + BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("href", GOV_LEGAL_ADVICE_URL) + BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("rel", "noreferrer noopener") + BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("target", "_blank") + } + } - @Test - fun `Submitting a non-numerical rentAmount returns an error`(page: Page) { - val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage() - rentAmountPage.submitRentAmount("not-a-number") - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") - } + @Nested + inner class ManagingJointLandlords { + @Test + fun `Submitting remove a joint landlord with no option selected returns an error`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") - @Test - fun `Submitting a rentAmount of 10000000 or above returns an error`(page: Page) { - val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage() - rentAmountPage.submitRentAmount("10000000") - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") - } + val checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - @Nested - inner class ConditionalContentPerRentFrequency { - @Test - fun `Page renders correctly for weekly rent frequency`(page: Page) { - val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage(RentFrequency.WEEKLY) - BaseComponent - .assertThat(rentAmountPage.header) - .containsText("What is the weekly rent?") - BaseComponent - .assertThat(rentAmountPage.subheading) - .containsText("Weekly rent") - BaseComponent - .assertThat(rentAmountPage.billsExplanationForRentFrequency) - .containsText("The amount you enter must be the total weekly rent agreed with the tenant.") - BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() - } - - @Test - fun `Page renders correctly for four weekly rent frequency`(page: Page) { - val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage(RentFrequency.FOUR_WEEKLY) - BaseComponent - .assertThat(rentAmountPage.header) - .containsText("What is the 4-weekly rent?") - BaseComponent - .assertThat(rentAmountPage.subheading) - .containsText("4-weekly rent") - BaseComponent - .assertThat(rentAmountPage.billsExplanationForRentFrequency) - .containsText("The amount you enter must be the total 4-weekly rent agreed with the tenant.") - BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() - } - - @Test - fun `Page renders correctly for monthly rent frequency`(page: Page) { - val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage(RentFrequency.MONTHLY) - BaseComponent - .assertThat(rentAmountPage.header) - .containsText("What is the monthly rent?") - BaseComponent - .assertThat(rentAmountPage.subheading) - .containsText("Monthly rent") - BaseComponent - .assertThat(rentAmountPage.billsExplanationForRentFrequency) - .containsText("The amount you enter must be the total monthly rent agreed with the tenant.") - BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() - } - - @Test - fun `Page renders correctly for 'other' rent frequency`(page: Page) { - val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage(RentFrequency.OTHER) - BaseComponent - .assertThat(rentAmountPage.header) - .containsText("What is the monthly rent?") - BaseComponent - .assertThat(rentAmountPage.subheading) - .containsText("Monthly rent") - BaseComponent - .assertThat(rentAmountPage.billsExplanationForRentFrequency) - .containsText("The amount you enter must be the total monthly rent agreed with the tenant.") - BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isVisible() - } - } + val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.form.submit() + assertThat(removeJointLandlordPage.form.getErrorMessage()) + .containsText("Select if you want to remove this joint landlord") } - @Nested - inner class HasJointLandlordsStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val hasJointLandlordsPage = navigator.skipToPropertyRegistrationHasJointLandlordsPage() - hasJointLandlordsPage.form.submit() - assertThat(hasJointLandlordsPage.form.getErrorMessage()) - .containsText("Select if there are any other landlords for this property") - } + @Test + fun `Submitting remove a joint landlord with No selected returns to the check page without removing the landlord`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") - @Test - fun `The link renders correctly`(page: Page) { - val hasJointLandlordsPage = navigator.skipToPropertyRegistrationHasJointLandlordsPage() - BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("href", GOV_LEGAL_ADVICE_URL) - BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("rel", "noreferrer noopener") - BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("target", "_blank") - } - } + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - @Nested - inner class ManagingJointLandlords { - @Test - fun `Submitting remove a joint landlord with no option selected returns an error`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") + val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.submitDoesNotWantToProceed() - val checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + } - val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.form.submit() - assertThat(removeJointLandlordPage.form.getErrorMessage()) - .containsText("Select if you want to remove this joint landlord") - } + @Test + fun `Clicking cancel returns to the check page regardless of selected remove answer`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") - @Test - fun `Submitting remove a joint landlord with No selected returns to the check page without removing the landlord`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.form.addAnotherButton.clickAndWait() - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + inviteAnotherJointLandlordPage.submitEmail("beta@example.com") - val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.submitDoesNotWantToProceed() + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - } + var removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.form.areYouSureRadios.selectValue("true") + removeJointLandlordPage.cancelLink.clickAndWait() - @Test - fun `Clicking cancel returns to the check page regardless of selected remove answer`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.form.addAnotherButton.clickAndWait() + removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.form.areYouSureRadios.selectValue("false") + removeJointLandlordPage.cancelLink.clickAndWait() - val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - inviteAnotherJointLandlordPage.submitEmail("beta@example.com") + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") + } - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + @Test + fun `Removing joint landlords works as expected`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") - var removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.form.areYouSureRadios.selectValue("true") - removeJointLandlordPage.cancelLink.clickAndWait() + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.form.addAnotherButton.clickAndWait() - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + inviteAnotherJointLandlordPage.submitEmail("beta@example.com") - removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.form.areYouSureRadios.selectValue("false") - removeJointLandlordPage.cancelLink.clickAndWait() + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") - } + var removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.submitWantsToProceed() - @Test - fun `Removing joint landlords works as expected`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("beta@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.form.addAnotherButton.clickAndWait() + removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.submitWantsToProceed() - val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - inviteAnotherJointLandlordPage.submitEmail("beta@example.com") + assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + } - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + @Test + fun `Editing joint landlords works as expected`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") - var removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.submitWantsToProceed() + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.form.addAnotherButton.clickAndWait() - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("beta@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + var inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + inviteAnotherJointLandlordPage.submitEmail("beta@example.com") - removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.submitWantsToProceed() + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Change") - assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - } + inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + BaseComponent.assertThat(inviteAnotherJointLandlordPage.form.emailInput).hasValue("alpha@example.com") + inviteAnotherJointLandlordPage.submitEmail("gamma@example.com") - @Test - fun `Editing joint landlords works as expected`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("gamma@example.com") + } - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.form.addAnotherButton.clickAndWait() + @Test + fun `Numbering on page and tables is correct`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") - var inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - inviteAnotherJointLandlordPage.submitEmail("beta@example.com") + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") + assertThat(checkJointLandlordPage.summaryList.firstRow.key).containsText("Joint landlord 1") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + checkJointLandlordPage.form.addAnotherButton.clickAndWait() - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Change") + val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + inviteAnotherJointLandlordPage.submitEmail("beta@example.com") - inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - BaseComponent.assertThat(inviteAnotherJointLandlordPage.form.emailInput).hasValue("alpha@example.com") - inviteAnotherJointLandlordPage.submitEmail("gamma@example.com") + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") + assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).key).containsText("Joint landlord 2") + assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("gamma@example.com") - } + val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.submitWantsToProceed() - @Test - fun `Numbering on page and tables is correct`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") - - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") - assertThat(checkJointLandlordPage.summaryList.firstRow.key).containsText("Joint landlord 1") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - checkJointLandlordPage.form.addAnotherButton.clickAndWait() - - val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - inviteAnotherJointLandlordPage.submitEmail("beta@example.com") - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") - assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).key).containsText("Joint landlord 2") - assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - - val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.submitWantsToProceed() - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") - assertThat(checkJointLandlordPage.summaryList.firstRow.key).containsText("Joint landlord 1") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("beta@example.com") - } + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") + assertThat(checkJointLandlordPage.summaryList.firstRow.key).containsText("Joint landlord 1") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("beta@example.com") } + } - @Nested - inner class InviteJointLandlordsStep { - @Test - fun `Submitting with no email returns an error`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("") - assertThat(inviteJointLandlordsPage.form.getErrorMessage()) - .containsText("Enter an email address in the correct format, like name@example.com") - } + @Nested + inner class InviteJointLandlordsStep { + @Test + fun `Submitting with no email returns an error`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("") + assertThat(inviteJointLandlordsPage.form.getErrorMessage()) + .containsText("Enter an email address in the correct format, like name@example.com") + } + + @Test + fun `Submitting with an invalid email returns an error`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("not-an-email") + assertThat(inviteJointLandlordsPage.form.getErrorMessage()) + .containsText("Enter an email address in the correct format, like name@example.com") + } + } - @Test - fun `Submitting with an invalid email returns an error`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("not-an-email") - assertThat(inviteJointLandlordsPage.form.getErrorMessage()) - .containsText("Enter an email address in the correct format, like name@example.com") - } + @Nested + inner class InviteAnotherJointLandlordsStep { + @Test + fun `Submitting with an already invited email returns an error`(page: Page) { + val alreadyInvitedEmail = "already@invited.com" + val inviteJointLandlordsPage = + navigator.skipToPropertyRegistrationInviteAnotherJointLandlordPage(mutableListOf(alreadyInvitedEmail)) + inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) + assertThat(inviteJointLandlordsPage.form.getErrorMessage()) + .containsText("You have already invited this email address") } - @Nested - inner class InviteAnotherJointLandlordsStep { - @Test - fun `Submitting with an already invited email returns an error`(page: Page) { - val alreadyInvitedEmail = "already@invited.com" - val inviteJointLandlordsPage = - navigator.skipToPropertyRegistrationInviteAnotherJointLandlordPage(mutableListOf(alreadyInvitedEmail)) - inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) - assertThat(inviteJointLandlordsPage.form.getErrorMessage()) - .containsText("You have already invited this email address") - } + @Test + fun `Submitting with an invited email in edit mode is permitted`(page: Page) { + val alreadyInvitedEmail = "already@invited.com" - @Test - fun `Submitting with an invited email in edit mode is permitted`(page: Page) { - val alreadyInvitedEmail = "already@invited.com" + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Change") - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Change") + val editJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + BaseComponent.assertThat(editJointLandlordPage.form.emailInput).hasValue(alreadyInvitedEmail) + inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) - val editJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - BaseComponent.assertThat(editJointLandlordPage.form.emailInput).hasValue(alreadyInvitedEmail) - inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText(alreadyInvitedEmail) + } + } - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText(alreadyInvitedEmail) - } + @Nested + inner class HasGasSupplyStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage() + hasGasSupplyPage.form.submit() + assertThat(hasGasSupplyPage.form.getErrorMessage()).containsText("Select whether you have a gas supply or any gas appliances") } - @Nested - inner class HasGasSupplyStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage() - hasGasSupplyPage.form.submit() - assertThat( - hasGasSupplyPage.form.getErrorMessage(), - ).containsText("Select whether you have a gas supply or any gas appliances") - } - - @Test - fun `Submitting No navigates to the check you gas answers step`(page: Page) { - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage() - hasGasSupplyPage.submitHasNoGasSupply() - assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - } + @Test + fun `Submitting No navigates to the check you gas answers step`(page: Page) { + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage() + hasGasSupplyPage.submitHasNoGasSupply() + assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) } + } - @Nested - inner class HasGasSafetyCertStep { - @Test - fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { - val hasGasSafetyCertPage = navigator.skipToPropertyRegistrationHasGasCertPage() - hasGasSafetyCertPage.form.submitPrimaryButton() - assertThat( - hasGasSafetyCertPage.form.getErrorMessage(), - ).containsText("Select whether you have a gas safety certificate") - } + @Nested + inner class HasGasSafetyCertStep { + @Test + fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { + val hasGasSafetyCertPage = navigator.skipToPropertyRegistrationHasGasCertPage() + hasGasSafetyCertPage.form.submitPrimaryButton() + assertThat( + hasGasSafetyCertPage.form.getErrorMessage(), + ).containsText("Select whether you have a gas safety certificate") } + } - @Nested - inner class GasSafetyIssueDateStepTests { - @ParameterizedTest(name = "{0}") - @Suppress("ktlint:standard:max-line-length") - @MethodSource( - "uk.gov.communities.prsdb.webapp.testHelpers.parameterProviders.TodayOrPastDateValidationTestParameterProvider#provideInvalidDateStrings", - ) - fun `Submitting returns a corresponding error when`( - dayMonthYear: Triple, - expectedErrorMessage: String, - ) { - val (day, month, year) = dayMonthYear - val gasSafetyIssueDatePage = navigator.skipToPropertyRegistrationGasCertIssueDatePage() - gasSafetyIssueDatePage.submitDate(day, month, year) - assertThat(gasSafetyIssueDatePage.form.getErrorMessage()).containsText(expectedErrorMessage) - } + @Nested + inner class GasSafetyIssueDateStepTests { + @ParameterizedTest(name = "{0}") + @Suppress("ktlint:standard:max-line-length") + @MethodSource( + "uk.gov.communities.prsdb.webapp.testHelpers.parameterProviders.TodayOrPastDateValidationTestParameterProvider#provideInvalidDateStrings", + ) + fun `Submitting returns a corresponding error when`( + dayMonthYear: Triple, + expectedErrorMessage: String, + ) { + val (day, month, year) = dayMonthYear + val gasSafetyIssueDatePage = navigator.skipToPropertyRegistrationGasCertIssueDatePage() + gasSafetyIssueDatePage.submitDate(day, month, year) + assertThat(gasSafetyIssueDatePage.form.getErrorMessage()).containsText(expectedErrorMessage) } + } - @Nested - inner class CheckGasSafetyAnswersStep { - @Test - fun `No gas supply - gas supply change link navigates to has gas supply page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersNoGasSupply(), - ) - cyaPage.gasSupplySummaryList.gasSupplyRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - } + @Nested + inner class CheckGasSafetyAnswersStep { + @Test + fun `No gas supply - gas supply change link navigates to has gas supply page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersNoGasSupply(), + ) + cyaPage.gasSupplySummaryList.gasSupplyRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + } - @Test - fun `Uploaded cert - gas supply change link navigates to has gas supply page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), - ) - cyaPage.gasSupplySummaryList.gasSupplyRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - } + @Test + fun `Uploaded cert - gas supply change link navigates to has gas supply page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), + ) + cyaPage.gasSupplySummaryList.gasSupplyRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + } - @Test - fun `Uploaded cert - valid gas cert change link navigates to has gas cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), - ) - cyaPage.certSummaryList.validGasCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - } + @Test + fun `Uploaded cert - valid gas cert change link navigates to has gas cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), + ) + cyaPage.certSummaryList.validGasCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + } - @Test - fun `Uploaded cert - issue date change link navigates to issue date page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), - ) - cyaPage.certSummaryList.issueDateRow.clickFirstActionLinkAndWait() - assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - } + @Test + fun `Uploaded cert - issue date change link navigates to issue date page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), + ) + cyaPage.certSummaryList.issueDateRow.clickFirstActionLinkAndWait() + assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + } - @Test - fun `Uploaded cert - certificate change link navigates to check uploads page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), - ) - cyaPage.certSummaryList.yourCertificateRow.clickFirstActionLinkAndWait() - assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) - } + @Test + fun `Uploaded cert - certificate change link navigates to check uploads page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), + ) + cyaPage.certSummaryList.yourCertificateRow.clickFirstActionLinkAndWait() + assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) + } - @Test - fun `Provide later - gas cert change link navigates to has gas cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersProvideLater(), - ) - cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - } + @Test + fun `Provide later - gas cert change link navigates to has gas cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersProvideLater(), + ) + cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + } - @Test - fun `No cert - gas cert change link navigates to has gas cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersNoCert(), - ) - cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - } + @Test + fun `No cert - gas cert change link navigates to has gas cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersNoCert(), + ) + cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + } - @Test - fun `Cert expired - gas cert change link navigates to has gas cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersCertExpired(), - ) - cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - } + @Test + fun `Cert expired - gas cert change link navigates to has gas cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersCertExpired(), + ) + cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) } + } - @Nested - inner class HasElectricalCertStep { - @Test - fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { - val hasElectricalCertPage = navigator.skipToPropertyRegistrationHasElectricalCertPage() - hasElectricalCertPage.form.submitPrimaryButton() - assertThat( - hasElectricalCertPage.form.getErrorMessage(), - ).containsText("Select which electrical safety certificate you have") - } + @Nested + inner class HasElectricalCertStep { + @Test + fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { + val hasElectricalCertPage = navigator.skipToPropertyRegistrationHasElectricalCertPage() + hasElectricalCertPage.form.submitPrimaryButton() + assertThat( + hasElectricalCertPage.form.getErrorMessage(), + ).containsText("Select which electrical safety certificate you have") } + } - @Nested - inner class CheckElectricalSafetyAnswersStep { - @Test - fun `Cert uploaded EIC - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } + @Nested + inner class CheckElectricalSafetyAnswersStep { + @Test + fun `Cert uploaded EIC - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } - @Test - fun `Cert uploaded EIC - expiry date change link navigates to expiry date page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), - ) - cyaPage.summaryList.expiryDateRow.clickFirstActionLinkAndWait() - assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - } + @Test + fun `Cert uploaded EIC - expiry date change link navigates to expiry date page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), + ) + cyaPage.summaryList.expiryDateRow.clickFirstActionLinkAndWait() + assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + } - @Test - fun `Cert uploaded EIC - certificate change link navigates to check uploads page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), - ) - cyaPage.summaryList.yourCertificateRow.clickFirstActionLinkAndWait() - assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) - } + @Test + fun `Cert uploaded EIC - certificate change link navigates to check uploads page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), + ) + cyaPage.summaryList.yourCertificateRow.clickFirstActionLinkAndWait() + assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + } - @Test - fun `Cert uploaded EICR - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEicr(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } + @Test + fun `Cert uploaded EICR - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEicr(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } - @Test - fun `Provide later - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersProvideLater(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } + @Test + fun `Provide later - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersProvideLater(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } - @Test - fun `No cert - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersNoCert(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } + @Test + fun `No cert - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersNoCert(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } - @Test - fun `Cert expired - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersCertExpired(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } + @Test + fun `Cert expired - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersCertExpired(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) } + } - @Nested - inner class ElectricalCertExpiryDateStepTests { - @ParameterizedTest(name = "{0}") - @Suppress("ktlint:standard:max-line-length") - @MethodSource( - "uk.gov.communities.prsdb.webapp.testHelpers.parameterProviders.AnyDateValidationTestParameterProvider#provideInvalidDateStrings", - ) - fun `Submitting returns a corresponding error when`( - dayMonthYear: Triple, - expectedErrorMessage: String, - ) { - val (day, month, year) = dayMonthYear - val electricalCertExpiryDatePage = navigator.skipToPropertyRegistrationElectricalCertExpiryDatePage() - electricalCertExpiryDatePage.submitDate(day, month, year) - assertThat(electricalCertExpiryDatePage.form.getErrorMessage()).containsText(expectedErrorMessage) - } + @Nested + inner class ElectricalCertExpiryDateStepTests { + @ParameterizedTest(name = "{0}") + @Suppress("ktlint:standard:max-line-length") + @MethodSource( + "uk.gov.communities.prsdb.webapp.testHelpers.parameterProviders.AnyDateValidationTestParameterProvider#provideInvalidDateStrings", + ) + fun `Submitting returns a corresponding error when`( + dayMonthYear: Triple, + expectedErrorMessage: String, + ) { + val (day, month, year) = dayMonthYear + val electricalCertExpiryDatePage = navigator.skipToPropertyRegistrationElectricalCertExpiryDatePage() + electricalCertExpiryDatePage.submitDate(day, month, year) + assertThat(electricalCertExpiryDatePage.form.getErrorMessage()).containsText(expectedErrorMessage) } + } - @Nested - inner class HasEpcStepTests { - @Test - fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { - val hasEpcPage = navigator.skipToPropertyRegistrationHasEpcPage() - hasEpcPage.form.submitPrimaryButton() - assertThat(hasEpcPage.form.getErrorMessage()) - .containsText("Select if you have an EPC for this property") - } + @Nested + inner class HasEpcStepTests { + @Test + fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { + val hasEpcPage = navigator.skipToPropertyRegistrationHasEpcPage() + hasEpcPage.form.submitPrimaryButton() + assertThat(hasEpcPage.form.getErrorMessage()) + .containsText("Select if you have an EPC for this property") } + } - @Nested - inner class FindYourEpcStepTests { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() - findYourEpcPage.form.submit() - assertThat(findYourEpcPage.form.getErrorMessage()) - .containsText("Enter a certificate number") - } + @Nested + inner class FindYourEpcStepTests { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() + findYourEpcPage.form.submit() + assertThat(findYourEpcPage.form.getErrorMessage()) + .containsText("Enter a certificate number") } + } - @Nested - inner class ConfirmEpcDetailsRetrievedByCertificateNumberStepTests { - @Test - fun `User sees a validation error when they do not select an answer`(page: Page) { - val confirmEpcDetailsPage = - navigator.skipToPropertyRegistrationConfirmEpcDetailsRetrievedByCertificateNumberPage() - confirmEpcDetailsPage.form.submit() - assertThat(confirmEpcDetailsPage.form.getErrorMessage()) - .containsText("Select if you want to use this EPC") - } + @Nested + inner class ConfirmEpcDetailsRetrievedByCertificateNumberStepTests { + @Test + fun `User sees a validation error when they do not select an answer`(page: Page) { + val confirmEpcDetailsPage = + navigator.skipToPropertyRegistrationConfirmEpcDetailsRetrievedByCertificateNumberPage() + confirmEpcDetailsPage.form.submit() + assertThat(confirmEpcDetailsPage.form.getErrorMessage()) + .containsText("Select if you want to use this EPC") } + } - @Nested - inner class IsEpcRequiredStepTests { - @Test - fun `Submitting with no option selected returns a validation error`(page: Page) { - val isEpcRequiredPage = navigator.skipToPropertyRegistrationIsEpcRequiredPage() - isEpcRequiredPage.form.submit() - assertThat(isEpcRequiredPage.form.getErrorMessage()) - .containsText("Select if an EPC is required to let this property") - } + @Nested + inner class IsEpcRequiredStepTests { + @Test + fun `Submitting with no option selected returns a validation error`(page: Page) { + val isEpcRequiredPage = navigator.skipToPropertyRegistrationIsEpcRequiredPage() + isEpcRequiredPage.form.submit() + assertThat(isEpcRequiredPage.form.getErrorMessage()) + .containsText("Select if an EPC is required to let this property") } + } - @Nested - inner class ConfirmEpcDetailsByUprnStepTests { - @Test - fun `User sees a validation error when they do not select an answer`(page: Page) { - val confirmEpcDetailsPage = - navigator.skipToPropertyRegistrationConfirmEpcDetailsByUprnPage() - confirmEpcDetailsPage.form.submit() - assertThat(confirmEpcDetailsPage.form.getErrorMessage()) - .containsText("Select if you want to use the EPC we found for your property") - } + @Nested + inner class ConfirmEpcDetailsByUprnStepTests { + @Test + fun `User sees a validation error when they do not select an answer`(page: Page) { + val confirmEpcDetailsPage = + navigator.skipToPropertyRegistrationConfirmEpcDetailsByUprnPage() + confirmEpcDetailsPage.form.submit() + assertThat(confirmEpcDetailsPage.form.getErrorMessage()) + .containsText("Select if you want to use the EPC we found for your property") } + } - @Nested - inner class MeesExemptionStepTests { - @Test - fun `User sees a validation error when they do not select a MEES exemption reason`(page: Page) { - val meesExemptionPage = navigator.skipToPropertyRegistrationMeesExemptionPage() + @Nested + inner class MeesExemptionStepTests { + @Test + fun `User sees a validation error when they do not select a MEES exemption reason`(page: Page) { + val meesExemptionPage = navigator.skipToPropertyRegistrationMeesExemptionPage() - meesExemptionPage.form.submit() + meesExemptionPage.form.submit() - assertPageIs(page, MeesExemptionFormPagePropertyRegistration::class) - assertThat(meesExemptionPage.form.getErrorMessage()) - .containsText("Select the energy efficiency exemption you registered for this property") - } + assertPageIs(page, MeesExemptionFormPagePropertyRegistration::class) + assertThat(meesExemptionPage.form.getErrorMessage()) + .containsText("Select the energy efficiency exemption you registered for this property") } + } - @Nested - inner class EpcExemptionStepTests { - @Test - fun `User sees a validation error when they do not select an EPC exemption reason`(page: Page) { - val epcExemptionPage = navigator.skipToPropertyRegistrationEpcExemptionPage() + @Nested + inner class EpcExemptionStepTests { + @Test + fun `User sees a validation error when they do not select an EPC exemption reason`(page: Page) { + val epcExemptionPage = navigator.skipToPropertyRegistrationEpcExemptionPage() - epcExemptionPage.form.submit() + epcExemptionPage.form.submit() - assertPageIs(page, EpcExemptionFormPagePropertyRegistration::class) - assertThat(epcExemptionPage.form.getErrorMessage()).isVisible() - } + assertPageIs(page, EpcExemptionFormPagePropertyRegistration::class) + assertThat(epcExemptionPage.form.getErrorMessage()).isVisible() } + } - @Nested - inner class Confirmation { - @Test - fun `Navigating here with an incomplete form returns a 400 error page`(page: Page) { - navigator.navigateToPropertyRegistrationConfirmationPage() - val errorPage = assertPageIs(page, ErrorPage::class) - BaseComponent.assertThat(errorPage.heading).containsText("Sorry, there is a problem with the service") - } + @Nested + inner class Confirmation { + @Test + fun `Navigating here with an incomplete form returns a 400 error page`(page: Page) { + navigator.navigateToPropertyRegistrationConfirmationPage() + val errorPage = assertPageIs(page, ErrorPage::class) + BaseComponent.assertThat(errorPage.heading).containsText("Sorry, there is a problem with the service") } + } - @Nested - inner class PropertyRegistrationStepCheckAnswers { - @Test - fun `After changing an answer, submitting a full section saves the state and returns the CYA page`(page: Page) { - val taskListPage = - navigator.goToRestructuredPropertyRegistrationTaskList( - PropertyStateSessionBuilder - .beforePropertyRegistrationCheckAnswers() - .withBedrooms(), - ) - taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - var checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - checkAnswersPage.summaryList.ownershipRow.actions.firstActionLink - .clickAndWait() - val ownershipPage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) - - ownershipPage.submitOwnershipType(OwnershipType.LEASEHOLD) - checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - checkAnswersPage.summaryList.licensingRow.actions.firstActionLink - .clickAndWait() - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - - licensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) - val licenceNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyRegistration::class) - licenceNumberPage.submitLicenseNumber("licence number") - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - // Confirmation - verify record saved - val savedJourneyStateCaptor = captor() - verify(savedJourneyStateRepository, times(2)).save(savedJourneyStateCaptor.capture()) - val savedJourneyStateAfterOwnershipUpdate = savedJourneyStateCaptor.allValues[0] - val savedJourneyStateAfterLicensingUpdate = savedJourneyStateCaptor.allValues[1] - assertTrue(savedJourneyStateAfterOwnershipUpdate.serializedState.contains("ownershipType\":\"LEASEHOLD\"")) - assertTrue(savedJourneyStateAfterOwnershipUpdate.serializedState.contains("licensingType\":\"NO_LICENSING\"")) - assertTrue(savedJourneyStateAfterLicensingUpdate.serializedState.contains("licensingType\":\"HMO_ADDITIONAL_LICENCE\"")) - assertTrue(savedJourneyStateAfterLicensingUpdate.serializedState.contains("licenceNumber\":\"licence number\"")) - } + @Nested + inner class PropertyRegistrationStepCheckAnswers { + @Test + fun `After changing an answer, submitting a full section saves the state and returns the CYA page`(page: Page) { + var checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() + + checkAnswersPage.summaryList.ownershipRow.actions.firstActionLink + .clickAndWait() + val ownershipPage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + + ownershipPage.submitOwnershipType(OwnershipType.LEASEHOLD) + checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + checkAnswersPage.summaryList.licensingRow.actions.firstActionLink + .clickAndWait() + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + + licensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) + val licenceNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyRegistration::class) + licenceNumberPage.submitLicenseNumber("licence number") + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + // Confirmation - verify record saved + val savedJourneyStateCaptor = captor() + verify(savedJourneyStateRepository, times(2)).save(savedJourneyStateCaptor.capture()) + val savedJourneyStateAfterOwnershipUpdate = savedJourneyStateCaptor.allValues[0] + val savedJourneyStateAfterLicensingUpdate = savedJourneyStateCaptor.allValues[1] + assertTrue(savedJourneyStateAfterOwnershipUpdate.serializedState.contains("ownershipType\":\"LEASEHOLD\"")) + assertTrue(savedJourneyStateAfterOwnershipUpdate.serializedState.contains("licensingType\":\"NO_LICENSING\"")) + assertTrue(savedJourneyStateAfterLicensingUpdate.serializedState.contains("licensingType\":\"HMO_ADDITIONAL_LICENCE\"")) + assertTrue(savedJourneyStateAfterLicensingUpdate.serializedState.contains("licenceNumber\":\"licence number\"")) + } + + @Test + fun `the gas supply change link starts a CYA sub-journey that returns to the property registration CYA on submit`(page: Page) { + val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() + checkAnswersPage.complianceSummaryList.gasSupplyRow.clickFirstActionLinkAndWait() + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + hasGasSupplyPage.submitHasNoGasSupply() + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + } + + @Test + fun `the electrical certificate change link navigates to the has electrical certificate page`(page: Page) { + val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() + checkAnswersPage.complianceSummaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } + + @Test + fun `the EPC change link takes the user to the confirm epc step if epc is found by uprn`(page: Page) { + whenever(epcRegisterClient.getByUprn(PropertyRegistrationJourneyTests.uprnForSelectedAddress)) + .thenReturn(MockEpcData.createEpcRegisterClientEpcFoundResponse()) + + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersCompliantEpc(), + ) - @Test - fun `the gas supply change link starts a CYA sub-journey that returns to the property registration CYA on submit`(page: Page) { - val taskListPage = - navigator.goToRestructuredPropertyRegistrationTaskList( - PropertyStateSessionBuilder - .beforePropertyRegistrationCheckAnswers() - .withBedrooms(), - ) - taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - checkAnswersPage.complianceSummaryList.gasSupplyRow.clickFirstActionLinkAndWait() - val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - hasGasSupplyPage.submitHasNoGasSupply() - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - } + cyaPage.epcCard + .getAction("Change") + .link + .clickAndWait() + assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) + } - @Test - fun `the electrical certificate change link navigates to the has electrical certificate page`(page: Page) { - val taskListPage = - navigator.goToRestructuredPropertyRegistrationTaskList( - PropertyStateSessionBuilder - .beforePropertyRegistrationCheckAnswers() - .withBedrooms(), - ) - taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - checkAnswersPage.complianceSummaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } + @Test + fun `the EPC change link takes the user to the has epc step if epc is found by certificate number`(page: Page) { + whenever(epcRegisterClient.getByUprn(PropertyRegistrationJourneyTests.uprnForSelectedAddress)) + .thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - @Test - fun `the EPC change link takes the user to the confirm epc step if epc is found by uprn`(page: Page) { - whenever(epcRegisterClient.getByUprn(PropertyRegistrationJourneyTests.uprnForSelectedAddress)) - .thenReturn(MockEpcData.createEpcRegisterClientEpcFoundResponse()) - - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersCompliantEpc(), - ) - - cyaPage.epcCard - .getAction("Change") - .link - .clickAndWait() - assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) - } + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckAnswersEpcFoundByCertificateNumber(), + ) + cyaPage.epcCard + .getAction("Change") + .link + .clickAndWait() + assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + } - @Test - fun `the EPC change link takes the user to the has epc step if epc is found by certificate number`(page: Page) { - whenever(epcRegisterClient.getByUprn(PropertyRegistrationJourneyTests.uprnForSelectedAddress)) - .thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckAnswersEpcFoundByCertificateNumber(), - ) - cyaPage.epcCard - .getAction("Change") - .link - .clickAndWait() - assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - } + @Test + fun `the licensing number change link navigates to the licensing page`(page: Page) { + val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPageWithSelectiveLicence() + checkAnswersPage.summaryList.licensingNumberRow.clickFirstActionLinkAndWait() + val selectiveLicencePage = assertPageIs(page, SelectiveLicenceFormPagePropertyRegistration::class) + selectiveLicencePage.submitLicenseNumber("SL-99999") + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + } + } - @Test - fun `the licensing number change link navigates to the licensing page`(page: Page) { - val taskListPage = - navigator.goToRestructuredPropertyRegistrationTaskList( - PropertyStateSessionBuilder - .beforePropertyRegistrationCheckAnswersWithSelectiveLicence() - .withBedrooms(), - ) - taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - checkAnswersPage.summaryList.licensingNumberRow.clickFirstActionLinkAndWait() - val selectiveLicencePage = assertPageIs(page, SelectiveLicenceFormPagePropertyRegistration::class) - selectiveLicencePage.submitLicenseNumber("SL-99999") - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - } + @Nested + inner class EpcInDateAtStartOfTenancyCheckStep { + @Test + fun `Submitting with no option selected returns an error`() { + val epcInDateAtStartOfTenancyCheckPage = navigator.skipToPropertyRegistrationEpcInDateAtStartOfTenancyCheckPage() + epcInDateAtStartOfTenancyCheckPage.form.submit() + assertThat(epcInDateAtStartOfTenancyCheckPage.form.getErrorMessage()) + .containsText("Select if the EPC was still in date when the current tenancy began") } - @Nested - inner class EpcInDateAtStartOfTenancyCheckStep { - @Test - fun `Submitting with no option selected returns an error`() { - val epcInDateAtStartOfTenancyCheckPage = navigator.skipToPropertyRegistrationEpcInDateAtStartOfTenancyCheckPage() - epcInDateAtStartOfTenancyCheckPage.form.submit() - assertThat(epcInDateAtStartOfTenancyCheckPage.form.getErrorMessage()) - .containsText("Select if the EPC was still in date when the current tenancy began") - } + @Test + fun `Page displays the EPC expiry date in the body text and Yes radio hint`() { + val epcInDateAtStartOfTenancyCheckPage = navigator.skipToPropertyRegistrationEpcInDateAtStartOfTenancyCheckPage() + assertThat(epcInDateAtStartOfTenancyCheckPage.bodyParagraph).containsText("5 January 2022") + assertThat(epcInDateAtStartOfTenancyCheckPage.form.yesHint).containsText("5 January 2022") + } + } - @Test - fun `Page displays the EPC expiry date in the body text and Yes radio hint`() { - val epcInDateAtStartOfTenancyCheckPage = navigator.skipToPropertyRegistrationEpcInDateAtStartOfTenancyCheckPage() - assertThat(epcInDateAtStartOfTenancyCheckPage.bodyParagraph).containsText("5 January 2022") - assertThat(epcInDateAtStartOfTenancyCheckPage.form.yesHint).containsText("5 January 2022") - } + @Nested + inner class HasMeesExemptionStep { + @Test + fun `Submitting with no option selected returns an error`() { + val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() + hasMeesExemptionPage.form.submit() + assertThat(hasMeesExemptionPage.form.getErrorMessage()) + .containsText("Select if you have a registered energy efficiency exemption for this property") } + } - @Nested - inner class HasMeesExemptionStep { - @Test - fun `Submitting with no option selected returns an error`() { - val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() - hasMeesExemptionPage.form.submit() - assertThat(hasMeesExemptionPage.form.getErrorMessage()) - .containsText("Select if you have a registered energy efficiency exemption for this property") - } + @Nested + inner class EpcMissingStep { + @Test + fun `The page renders the occupied variant for an occupied property`(page: Page) { + val epcMissingPage = navigator.skipToPropertyRegistrationEpcMissingPage(propertyIsOccupied = true) + BaseComponent.assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + BaseComponent.assertThat(epcMissingPage.warning).isVisible() + BaseComponent.assertThat(epcMissingPage.continueAnywayButton).hasText("Continue anyway") + } + + @Test + fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { + val epcMissingPage = navigator.skipToPropertyRegistrationEpcMissingPage(propertyIsOccupied = false) + BaseComponent.assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + BaseComponent.assertThat(epcMissingPage.warning).isHidden() + BaseComponent.assertThat(epcMissingPage.continueButton).hasText("Continue") } + } - @Nested - inner class EpcMissingStep { - @Test - fun `The page renders the occupied variant for an occupied property`(page: Page) { - val epcMissingPage = navigator.skipToPropertyRegistrationEpcMissingPage(propertyIsOccupied = true) - BaseComponent.assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - BaseComponent.assertThat(epcMissingPage.warning).isVisible() - BaseComponent.assertThat(epcMissingPage.continueAnywayButton).hasText("Continue anyway") - } + @Nested + inner class EpcExpiredStep { + @Test + fun `The page renders the occupied variant for an occupied property`(page: Page) { + val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = true) + BaseComponent.assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") + BaseComponent.assertThat(epcExpiredPage.warning).isVisible() + BaseComponent.assertThat(epcExpiredPage.submitButton).hasText("Continue anyway") + } - @Test - fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { - val epcMissingPage = navigator.skipToPropertyRegistrationEpcMissingPage(propertyIsOccupied = false) - BaseComponent.assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - BaseComponent.assertThat(epcMissingPage.warning).isHidden() - BaseComponent.assertThat(epcMissingPage.continueButton).hasText("Continue") - } + @Test + fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { + val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = false) + BaseComponent.assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") + BaseComponent.assertThat(epcExpiredPage.warning).isHidden() + BaseComponent.assertThat(epcExpiredPage.submitButton).hasText("Continue") } - @Nested - inner class EpcExpiredStep { - @Test - fun `The page renders the occupied variant for an occupied property`(page: Page) { - val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = true) - BaseComponent.assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") - BaseComponent.assertThat(epcExpiredPage.warning).isVisible() - BaseComponent.assertThat(epcExpiredPage.submitButton).hasText("Continue anyway") - } + @Test + fun `The expiry date is displayed in bold on the occupied variant`(page: Page) { + val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = true) + assertThat(epcExpiredPage.expiryDateParagraph.locator("strong")).hasText("5 January 2022") + } - @Test - fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { - val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = false) - BaseComponent.assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") - BaseComponent.assertThat(epcExpiredPage.warning).isHidden() - BaseComponent.assertThat(epcExpiredPage.submitButton).hasText("Continue") - } + @Test + fun `The expiry date is displayed in bold on the unoccupied variant`(page: Page) { + val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = false) + assertThat(epcExpiredPage.expiryDateParagraph.locator("strong")).hasText("5 January 2022") + } + } - @Test - fun `The expiry date is displayed in bold on the occupied variant`(page: Page) { - val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = true) - assertThat(epcExpiredPage.expiryDateParagraph.locator("strong")).hasText("5 January 2022") - } + @Nested + inner class LowEnergyRatingStep { + @Test + fun `The page renders the occupied variant for an occupied property`(page: Page) { + val lowEnergyRatingPage = navigator.skipToPropertyRegistrationLowEnergyRatingPage(propertyIsOccupied = true) + BaseComponent.assertThat(lowEnergyRatingPage.heading).containsText( + "This property does not meet energy efficiency requirements for letting", + ) + BaseComponent.assertThat(lowEnergyRatingPage.continueAnywayButton).containsText("Continue anyway") + } - @Test - fun `The expiry date is displayed in bold on the unoccupied variant`(page: Page) { - val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = false) - assertThat(epcExpiredPage.expiryDateParagraph.locator("strong")).hasText("5 January 2022") - } + @Test + fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { + val lowEnergyRatingPage = navigator.skipToPropertyRegistrationLowEnergyRatingPage(propertyIsOccupied = false) + BaseComponent.assertThat(lowEnergyRatingPage.heading).containsText( + "You’ll need to get a new EPC before letting this property", + ) + BaseComponent.assertThat(lowEnergyRatingPage.continueButton).containsText("Continue") } + } - @Nested - inner class LowEnergyRatingStep { - @Test - fun `The page renders the occupied variant for an occupied property`(page: Page) { - val lowEnergyRatingPage = navigator.skipToPropertyRegistrationLowEnergyRatingPage(propertyIsOccupied = true) - BaseComponent.assertThat(lowEnergyRatingPage.heading).containsText( - "This property does not meet energy efficiency requirements for letting", - ) - BaseComponent.assertThat(lowEnergyRatingPage.continueAnywayButton).containsText("Continue anyway") - } + @Nested + inner class ProvideEpcLaterStep { + @Test + fun `The page renders the occupied variant for an occupied property`(page: Page) { + val provideEpcLaterPage = navigator.skipToPropertyRegistrationProvideEpcLaterPage(propertyIsOccupied = true) + BaseComponent.assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") + BaseComponent.assertThat(provideEpcLaterPage.insetText).containsText( + "To keep the property registered, we need all its compliance certificates within 28 days.", + ) + } - @Test - fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { - val lowEnergyRatingPage = navigator.skipToPropertyRegistrationLowEnergyRatingPage(propertyIsOccupied = false) - BaseComponent.assertThat(lowEnergyRatingPage.heading).containsText( - "You’ll need to get a new EPC before letting this property", - ) - BaseComponent.assertThat(lowEnergyRatingPage.continueButton).containsText("Continue") - } + @Test + fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { + val provideEpcLaterPage = navigator.skipToPropertyRegistrationProvideEpcLaterPage(propertyIsOccupied = false) + BaseComponent.assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") + BaseComponent.assertThat(provideEpcLaterPage.insetText).isHidden() } + } - @Nested - inner class ProvideEpcLaterStep { - @Test - fun `The page renders the occupied variant for an occupied property`(page: Page) { - val provideEpcLaterPage = navigator.skipToPropertyRegistrationProvideEpcLaterPage(propertyIsOccupied = true) - BaseComponent.assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") - BaseComponent.assertThat(provideEpcLaterPage.insetText).containsText( - "To keep the property registered, we need all its compliance certificates within 28 days.", + @Nested + inner class CheckEpcAnswersStep { + @Test + fun `Shows EPC card with meets requirements inset for a compliant unexpired EPC`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersCompliantEpc(), ) - } - @Test - fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { - val provideEpcLaterPage = navigator.skipToPropertyRegistrationProvideEpcLaterPage(propertyIsOccupied = false) - BaseComponent.assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") - BaseComponent.assertThat(provideEpcLaterPage.insetText).isHidden() - } + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isVisible() + assertThat(cyaPage.epcExpiredText).isHidden() + assertThat(cyaPage.lowRatingText).isHidden() + assertThat(cyaPage.lowRatingOccupiedInset).isHidden() + assertThat(cyaPage.occupiedNoEpcInset).isHidden() } - @Nested - inner class CheckEpcAnswersStep { - @Test - fun `Shows EPC card with meets requirements inset for a compliant unexpired EPC`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersCompliantEpc(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isVisible() - assertThat(cyaPage.epcExpiredText).isHidden() - assertThat(cyaPage.lowRatingText).isHidden() - assertThat(cyaPage.lowRatingOccupiedInset).isHidden() - assertThat(cyaPage.occupiedNoEpcInset).isHidden() - } - - @Test - fun `Shows EPC card and MEES exemption rows for an unexpired EPC with low rating and exemption`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingWithExemption(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.lowRatingText).isVisible() - assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("Yes") - assertThat(cyaPage.rows.meesExemptionRow.value).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - assertThat(cyaPage.lowRatingOccupiedInset).isHidden() - } + @Test + fun `Shows EPC card and MEES exemption rows for an unexpired EPC with low rating and exemption`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingWithExemption(), + ) - @Test - fun `Shows EPC card, expired text, tenancy check row, and meets requirements inset for expired but valid EPC`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcInDateAtTenancyStart(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.epcExpiredText).isVisible() - assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") - assertThat(cyaPage.meetsRequirementsInset).isVisible() - assertThat(cyaPage.lowRatingText).isHidden() - } + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.lowRatingText).isVisible() + assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("Yes") + assertThat(cyaPage.rows.meesExemptionRow.value).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + assertThat(cyaPage.lowRatingOccupiedInset).isHidden() + } - @Test - fun `Shows EPC card, expired text, tenancy check, low rating text, and MEES rows for expired EPC with low rating and exemption`( - page: Page, - ) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcLowRatingWithExemption(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.epcExpiredText).isVisible() - assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") - assertThat(cyaPage.lowRatingText).isVisible() - assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("Yes") - assertThat(cyaPage.rows.meesExemptionRow.value).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - } + @Test + fun `Shows EPC card, expired text, tenancy check row, and meets requirements inset for expired but valid EPC`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcInDateAtTenancyStart(), + ) - @Test - fun `Shows hasEpc row with occupied provide-later text for occupied property choosing to provide EPC later`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersProvideLaterOccupied(), - ) - - assertThat(cyaPage.rows.hasEpcRow.value).containsText("Provide EPC details later") - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - } + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.epcExpiredText).isVisible() + assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") + assertThat(cyaPage.meetsRequirementsInset).isVisible() + assertThat(cyaPage.lowRatingText).isHidden() + } - @Test - fun `Shows hasEpc row with unoccupied provide-later text for unoccupied property choosing to provide EPC later`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersProvideLaterUnoccupied(), - ) - - assertThat(cyaPage.rows.hasEpcRow.value).containsText("within 28 days of the property being occupied") - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - } + @Test + fun `Shows EPC card, expired text, tenancy check, low rating text, and MEES rows for expired EPC with low rating and exemption`( + page: Page, + ) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcLowRatingWithExemption(), + ) - @Suppress("ktlint:standard:max-line-length") - @Test - fun `Shows EPC card, low rating text, no exemption row, and council inset for occupied property with low rating and no MEES exemption`( - page: Page, - ) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingNoExemptionOccupied(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.lowRatingText).isVisible() - assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("No") - assertThat(cyaPage.lowRatingOccupiedInset).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - } + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.epcExpiredText).isVisible() + assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") + assertThat(cyaPage.lowRatingText).isVisible() + assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("Yes") + assertThat(cyaPage.rows.meesExemptionRow.value).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + } - @Test - fun `Shows provide EPC later row for unoccupied property with low rating and no MEES exemption`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingNoExemptionUnoccupied(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - assertThat(cyaPage.rows.hasEpcRow.value) - .containsText("Provide EPC details later (within 28 days of the property being occupied)") - assertThat(cyaPage.lowRatingText).isHidden() - assertThat(cyaPage.lowRatingOccupiedInset).isHidden() - } + @Test + fun `Shows hasEpc row with occupied provide-later text for occupied property choosing to provide EPC later`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersProvideLaterOccupied(), + ) - @Test - fun `Shows hasEpc, isEpcRequired, and exemption reason rows for property with no EPC that is exempt`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersNoEpcExempt(), - ) - - assertThat(cyaPage.rows.hasEpcRow.value).containsText("No") - assertThat(cyaPage.rows.isEpcRequiredRow.value).containsText("No") - assertThat(cyaPage.rows.epcExemptionRow.value).isVisible() - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - assertThat(cyaPage.occupiedNoEpcInset).isHidden() - } + assertThat(cyaPage.rows.hasEpcRow.value).containsText("Provide EPC details later") + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + } - @Suppress("ktlint:standard:max-line-length") - @Test - fun `Shows EPC card, expired text, tenancy check, low rating text, no exemption row, and council inset for occupied property with expired low-rating EPC in date at tenancy start and no exemption`( - page: Page, - ) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcLowRatingNoExemptionOccupied(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.epcExpiredText).isVisible() - assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") - assertThat(cyaPage.lowRatingText).isVisible() - assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("No") - assertThat(cyaPage.lowRatingOccupiedInset).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - } + @Test + fun `Shows hasEpc row with unoccupied provide-later text for unoccupied property choosing to provide EPC later`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersProvideLaterUnoccupied(), + ) - @Test - fun `Shows hasEpc and isEpcRequired rows with council inset for occupied property with no EPC that is required`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersNoEpcOccupiedNotExempt(), - ) - - assertThat(cyaPage.rows.hasEpcRow.value).containsText("No") - assertThat(cyaPage.rows.isEpcRequiredRow.value).containsText("Yes") - assertThat(cyaPage.occupiedNoEpcInset).isVisible() - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - assertThat(cyaPage.rows.epcExemptionRow.key).isHidden() - } + assertThat(cyaPage.rows.hasEpcRow.value).containsText("within 28 days of the property being occupied") + BaseComponent.assertThat(cyaPage.epcCard).isHidden() } - @Nested - inner class ConfirmMissingComplianceStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val confirmPage = navigator.skipToPropertyRegistrationConfirmMissingCompliancePage() - confirmPage.form.submit() - assertThat(confirmPage.form.getErrorMessage()).containsText("Select whether you want to submit this registration") - } + @Suppress("ktlint:standard:max-line-length") + @Test + fun `Shows EPC card, low rating text, no exemption row, and council inset for occupied property with low rating and no MEES exemption`( + page: Page, + ) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingNoExemptionOccupied(), + ) - @Test - fun `Selecting no, go back redirects to the check answers page`(page: Page) { - val confirmPage = navigator.skipToPropertyRegistrationConfirmMissingCompliancePage() - confirmPage.form.radios.selectValue("false") - confirmPage.form.submit() - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - } + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.lowRatingText).isVisible() + assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("No") + assertThat(cyaPage.lowRatingOccupiedInset).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isHidden() } - } - // TODO PDJB-1340: Remove tests when the PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING Feature Flag is removed - @Nested - inner class RestructureAndSkippingDisabled { - @BeforeEach - fun disableRestructureAndSkippingFlag() { - featureFlagManager.disableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + @Test + fun `Shows provide EPC later row for unoccupied property with low rating and no MEES exemption`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingNoExemptionUnoccupied(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + assertThat(cyaPage.rows.hasEpcRow.value) + .containsText("Provide EPC details later (within 28 days of the property being occupied)") + assertThat(cyaPage.lowRatingText).isHidden() + assertThat(cyaPage.lowRatingOccupiedInset).isHidden() } - @Nested - inner class TaskListStep { - @Test - fun `Completing preceding steps will show a task as not started and completed steps as complete`(page: Page) { - navigator.skipToPropertyRegistrationHasJointLandlordsPage() - val taskListPage = navigator.goToPropertyRegistrationTaskList() - assert(taskListPage.taskHasStatus("Property address", "Complete")) - assert(taskListPage.taskHasStatus("Property type", "Complete")) - assert(taskListPage.taskHasStatus("How you own the property", "Complete")) - assert(taskListPage.taskHasStatus("If the property has a license", "Complete")) - assert(taskListPage.taskHasStatus("Tenancy and rental information", "Complete")) - assert(taskListPage.taskHasStatus("Invite joint landlords", "Not started")) - assert(taskListPage.taskHasStatus("Gas safety certificate", "Cannot start yet")) - assert(taskListPage.taskHasStatus("Electrical safety certificate", "Cannot start yet")) - assert(taskListPage.taskHasStatus("Energy performance certificate (EPC)", "Cannot start yet")) - } + @Test + fun `Shows hasEpc, isEpcRequired, and exemption reason rows for property with no EPC that is exempt`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersNoEpcExempt(), + ) - @Test - fun `EPC task (starting with an internal step) shows as Not Started when the user is on the first step they see`(page: Page) { - navigator.skipToPropertyRegistrationHasEpcPage() - val taskListPage = navigator.goToPropertyRegistrationTaskList() - assert(taskListPage.taskHasStatus("Energy performance certificate (EPC)", "Not started")) - } + assertThat(cyaPage.rows.hasEpcRow.value).containsText("No") + assertThat(cyaPage.rows.isEpcRequiredRow.value).containsText("No") + assertThat(cyaPage.rows.epcExemptionRow.value).isVisible() + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + assertThat(cyaPage.occupiedNoEpcInset).isHidden() + } + + @Suppress("ktlint:standard:max-line-length") + @Test + fun `Shows EPC card, expired text, tenancy check, low rating text, no exemption row, and council inset for occupied property with expired low-rating EPC in date at tenancy start and no exemption`( + page: Page, + ) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcLowRatingNoExemptionOccupied(), + ) - @Test - fun `Completing first step of a task will show a task as in progress and completed steps as complete`(page: Page) { - navigator.skipToPropertyRegistrationRentFrequencyPage() - val taskListPage = navigator.goToPropertyRegistrationTaskList() - assert(taskListPage.taskHasStatus("Property address", "Complete")) - assert(taskListPage.taskHasStatus("Property type", "Complete")) - assert(taskListPage.taskHasStatus("How you own the property", "Complete")) - assert(taskListPage.taskHasStatus("If the property has a license", "Complete")) - assert(taskListPage.taskHasStatus("Tenancy and rental information", "In progress")) - assert(taskListPage.taskHasStatus("Invite joint landlords", "Cannot start yet")) - assert(taskListPage.taskHasStatus("Gas safety certificate", "Cannot start yet")) - assert(taskListPage.taskHasStatus("Electrical safety certificate", "Cannot start yet")) - assert(taskListPage.taskHasStatus("Energy performance certificate (EPC)", "Cannot start yet")) - } + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.epcExpiredText).isVisible() + assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") + assertThat(cyaPage.lowRatingText).isVisible() + assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("No") + assertThat(cyaPage.lowRatingOccupiedInset).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isHidden() } - @Nested - inner class LookupAddressAndNoAddressFoundSteps { - @Test - fun `Submitting with empty data fields returns an error`(page: Page) { - val lookupAddressPage = navigator.goToPropertyRegistrationLookupAddressPage() - lookupAddressPage.clearForm() // There may be form answers in the journey state - lookupAddressPage.form.submit() - assertThat(lookupAddressPage.form.getErrorMessage("postcode")).containsText("Enter a postcode") - assertThat(lookupAddressPage.form.getErrorMessage("houseNameOrNumber")).containsText("Enter a house name or number") - } - - @Test - fun `If no English addresses are found, user can search again or enter address manually via the No Address Found step`( - page: Page, - ) { - // Lookup address finds no English results - val houseNumber = "NOT A HOUSE NUMBER" - val postcode = "NOT A POSTCODE" - var lookupAddressPage = navigator.goToPropertyRegistrationLookupAddressPage() - lookupAddressPage.submitPostcodeAndBuildingNameOrNumber(postcode, houseNumber) - - // redirect to noAddressFoundPage - var noAddressFoundPage = assertPageIs(page, NoAddressFoundFormPagePropertyRegistration::class) - BaseComponent - .assertThat(noAddressFoundPage.heading) - .containsText("No matching address in England found for $postcode and $houseNumber") - - // Search Again - noAddressFoundPage.searchAgain.clickAndWait() - lookupAddressPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - lookupAddressPage.submitPostcodeAndBuildingNameOrNumber(postcode, houseNumber) - - // Submit no address found page - noAddressFoundPage = assertPageIs(page, NoAddressFoundFormPagePropertyRegistration::class) - noAddressFoundPage.form.submit() - assertPageIs(page, ManualAddressFormPagePropertyRegistration::class) - } - } - - @Nested - inner class SelectAddressStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage() - selectAddressPage.form.submit() - assertThat(selectAddressPage.form.getErrorMessage()).containsText("Select an address") - } - - @Test - fun `Clicking Search Again navigates to the previous step`(page: Page) { - val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage() - selectAddressPage.searchAgain.clickAndWait() - assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - } - - @Test - fun `Selecting an already-registered address navigates to the AlreadyRegistered step`(page: Page) { - val alreadyRegisteredAddress = AddressDataModel("1 Example Road", uprn = 1123456) - val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage(listOf(alreadyRegisteredAddress)) - selectAddressPage.selectAddressAndSubmit(alreadyRegisteredAddress.singleLineAddress) - assertPageIs(page, AlreadyRegisteredFormPagePropertyRegistration::class) - } - } - - @Nested - inner class ManualAddressEntryStep { - @Test - fun `Submitting empty data fields returns errors`(page: Page) { - val manualAddressPage = navigator.skipToPropertyRegistrationManualAddressPage() - manualAddressPage.submitAddress() - assertThat(manualAddressPage.form.getErrorMessage("addressLineOne")) - .containsText("Enter the first line of an address, typically the building and street") - assertThat(manualAddressPage.form.getErrorMessage("townOrCity")).containsText("Enter town or city") - assertThat(manualAddressPage.form.getErrorMessage("postcode")).containsText("Enter postcode") - } - } - - @Nested - inner class SelectLocalCouncilStep { - @Test - fun `Submitting without selecting an LA return an error`(page: Page) { - val selectLocalCouncilPage = navigator.skipToPropertyRegistrationSelectLocalCouncilPage() - selectLocalCouncilPage.form.submit() - assertThat(selectLocalCouncilPage.form.getErrorMessage("localCouncilId")) - .containsText("Select a local council to continue") - } - } - - @Nested - inner class PropertyTypeStep { - @Test - fun `Submitting with no propertyType selected returns an error`(page: Page) { - val propertyTypePage = navigator.skipToPropertyRegistrationPropertyTypePage() - propertyTypePage.form.submit() - assertThat(propertyTypePage.form.getErrorMessage()).containsText("Select the type of property") - } - - @Test - fun `Submitting with the Other propertyType selected but an empty customPropertyType field returns an error`(page: Page) { - val propertyTypePage = navigator.skipToPropertyRegistrationPropertyTypePage() - propertyTypePage.submitCustomPropertyType("") - assertThat(propertyTypePage.form.getErrorMessage()).containsText("Enter the property type") - } - } - - @Nested - inner class OwnershipTypeStep { - @Test - fun `Submitting with no ownershipType selected returns an error`(page: Page) { - val ownershipTypePage = navigator.skipToPropertyRegistrationOwnershipTypePage() - ownershipTypePage.form.submit() - assertThat(ownershipTypePage.form.getErrorMessage()).containsText("Select the ownership type") - } - } - - @Nested - inner class LicensingTypeStep { - @Test - fun `Submitting with no licensingType selected returns an error`(page: Page) { - val licensingTypePage = navigator.skipToPropertyRegistrationLicensingTypePage() - licensingTypePage.form.submit() - assertThat(licensingTypePage.form.getErrorMessage()).containsText("Select the type of licensing for the property") - } - - @Test - fun `Submitting with an HMO mandatory licence redirects to the next step`(page: Page) { - val licensingTypePage = navigator.skipToPropertyRegistrationLicensingTypePage() - licensingTypePage.submitLicensingType(LicensingType.HMO_MANDATORY_LICENCE) - val licenseNumberPage = assertPageIs(page, HmoMandatoryLicenceFormPagePropertyRegistration::class) - BaseComponent - .assertThat(licenseNumberPage.form.sectionHeader) - .containsText("Section 1 of 2 — Add property details") - } - - @Test - fun `Submitting with an HMO additional licence redirects to the next step`(page: Page) { - val licensingTypePage = navigator.skipToPropertyRegistrationLicensingTypePage() - licensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) - val licenseNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyRegistration::class) - BaseComponent - .assertThat(licenseNumberPage.form.sectionHeader) - .containsText("Section 1 of 2 — Add property details") - } - } - - @Nested - inner class SelectiveLicenceStep { - @Test - fun `Submitting with no licence number returns an error`(page: Page) { - val selectiveLicencePage = navigator.skipToPropertyRegistrationSelectiveLicencePage() - selectiveLicencePage.form.submit() - assertThat(selectiveLicencePage.form.getErrorMessage()).containsText("Enter the selective licence number") - } - - @Test - fun `Submitting with a very long licence number returns an error`(page: Page) { - val selectiveLicencePage = navigator.skipToPropertyRegistrationSelectiveLicencePage() - val aVeryLongString = - "This string is very long, so long that it is not feasible that it is a real licence number " + - "- therefore if it is submitted there will in fact be an error rather than a successful submission." + - " It is actually quite difficult for a string to be long enough to trigger this error, because the" + - " maximum length has been selected to be permissive of id numbers we do not expect while still having " + - "a cap reachable with a little effort." - selectiveLicencePage.submitLicenseNumber(aVeryLongString) - assertThat(selectiveLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") - } - } - - @Nested - inner class HmoMandatoryLicenceStep { - @Test - fun `Submitting with a licence number redirects to the next step`(page: Page) { - val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationHmoMandatoryLicencePage() - hmoMandatoryLicencePage.submitLicenseNumber("licence number") - assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - } - - @Test - fun `Submitting with no licence number returns an error`(page: Page) { - val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationHmoMandatoryLicencePage() - hmoMandatoryLicencePage.form.submit() - assertThat(hmoMandatoryLicencePage.form.getErrorMessage()).containsText("Enter the HMO Mandatory licence number") - } - - @Test - fun `Submitting with a very long licence number returns an error`(page: Page) { - val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationHmoMandatoryLicencePage() - val aVeryLongString = - "This string is very long, so long that it is not feasible that it is a real licence number " + - "- therefore if it is submitted there will in fact be an error rather than a successful submission." + - " It is actually quite difficult for a string to be long enough to trigger this error, because the" + - " maximum length has been selected to be permissive of id numbers we do not expect while still having " + - "a cap reachable with a little effort." - hmoMandatoryLicencePage.submitLicenseNumber(aVeryLongString) - assertThat(hmoMandatoryLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") - } - } - - @Nested - inner class HmoAdditionalLicenceStep { - @Test - fun `Submitting with a licence number redirects to the next step`(page: Page) { - val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationHmoAdditionalLicencePage() - hmoAdditionalLicencePage.submitLicenseNumber("licence number") - assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - } - - @Test - fun `Submitting with no licence number returns an error`(page: Page) { - val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationHmoAdditionalLicencePage() - hmoAdditionalLicencePage.form.submit() - assertThat(hmoAdditionalLicencePage.form.getErrorMessage()).containsText("Enter the HMO additional licence number") - } - - @Test - fun `Submitting with a very long licence number returns an error`(page: Page) { - val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationHmoAdditionalLicencePage() - val aVeryLongString = - "This string is very long, so long that it is not feasible that it is a real licence number " + - "- therefore if it is submitted there will in fact be an error rather than a successful submission." + - " It is actually quite difficult for a string to be long enough to trigger this error, because the" + - " maximum length has been selected to be permissive of id numbers we do not expect while still having " + - "a cap reachable with a little effort." - hmoAdditionalLicencePage.submitLicenseNumber(aVeryLongString) - assertThat(hmoAdditionalLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") - } - } - - @Nested - inner class OccupancyStep { - @Test - fun `Submitting with no occupancy option selected returns an error`(page: Page) { - val occupancyPage = navigator.skipToPropertyRegistrationOccupancyPage() - occupancyPage.form.submit() - assertThat(occupancyPage.form.getErrorMessage()).containsText("Select whether the property is occupied") - } - } - - @Nested - inner class NumberOfHouseholdsStep { - @Test - fun `Submitting with a blank numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() - householdsPage.form.submit() - assertThat(householdsPage.form.getErrorMessage()).containsText("Enter how many separate households, like 1 or 2") - } - - @Test - fun `Submitting with a non-numerical value in the numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() - householdsPage.submitNumberOfHouseholds("not-a-number") - assertThat(householdsPage.form.getErrorMessage()) - .containsText("Enter how many separate households, like 1 or 2") - } - - @Test - fun `Submitting with a non-integer number in the numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() - householdsPage.submitNumberOfHouseholds("2.3") - assertThat(householdsPage.form.getErrorMessage()) - .containsText("Enter how many separate households, like 1 or 2") - } - - @Test - fun `Submitting with a negative integer in the numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() - householdsPage.submitNumberOfHouseholds(-2) - assertThat(householdsPage.form.getErrorMessage()) - .containsText("Enter how many separate households, like 1 or 2") - } - - @Test - fun `Submitting with a zero integer in the numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() - householdsPage.submitNumberOfHouseholds(0) - assertThat(householdsPage.form.getErrorMessage()) - .containsText("Enter how many separate households, like 1 or 2") - } - } - - @Nested - inner class NumberOfPeopleStep { - @Test - fun `Submitting with a blank numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() - peoplePage.form.submit() - assertThat(peoplePage.form.getErrorMessage()).containsText("Enter how many people, like 2 or 5") - } - - @Test - fun `Submitting with a non-numerical value in the numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() - peoplePage.submitNumOfPeople("not-a-number") - assertThat(peoplePage.form.getErrorMessage()) - .containsText("Enter how many people, like 2 or 5") - } - - @Test - fun `Submitting with a non-integer number in the numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() - peoplePage.submitNumOfPeople("2.3") - assertThat(peoplePage.form.getErrorMessage()) - .containsText("Enter how many people, like 2 or 5") - } - - @Test - fun `Submitting with a negative integer in the numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() - peoplePage.submitNumOfPeople("-2") - assertThat(peoplePage.form.getErrorMessage()) - .containsText("Enter how many people, like 2 or 5") - } - - @Test - fun `Submitting with a zero integer in the numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() - peoplePage.submitNumOfPeople(0) - assertThat(peoplePage.form.getErrorMessage()) - .containsText("Enter how many people, like 2 or 5") - } - - @Test - fun `Submitting with an integer in the numberOfPeople field that is less than the numberOfHouseholds returns an error`( - page: Page, - ) { - val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() - householdsPage.submitNumberOfHouseholds(3) - val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) - peoplePage.submitNumOfPeople(2) - assertThat(peoplePage.form.getErrorMessage()) - .containsText( - "The number of people in the property must be the same as or higher than the number of households in the property", - ) - } - } - - @Nested - inner class NumberOfBedroomsStep { - val numberOfBedroomsErrorMessage = "Enter the number of bedrooms, like 3 or 8" - - @Test - fun `Submitting with a blank numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.form.submit() - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } - - @Test - fun `Submitting with a non-numerical value in the numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.submitNumOfBedrooms("not-a-number") - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } - - @Test - fun `Submitting with a non-integer number in the numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.submitNumOfBedrooms("2.3") - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } - - @Test - fun `Submitting with a negative integer in the numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.submitNumOfBedrooms("-2") - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } - - @Test - fun `Submitting with a zero integer in the numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.submitNumOfBedrooms(0) - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } - } - - @Nested - inner class RentIncludesBillsStep { - @Test - fun `Submitting with no rent included option selected returns an error`(page: Page) { - val rentIncludesBillsPage = navigator.skipToPropertyRegistrationRentIncludesBillsPage() - rentIncludesBillsPage.form.submit() - assertThat(rentIncludesBillsPage.form.getErrorMessage()).containsText("Select whether the rent includes bills") - } - } - - @Nested - inner class BillsIncludedStep { - @Test - fun `Submitting with no bills included selected returns an error`(page: Page) { - val billsIncludedPage = navigator.skipToPropertyRegistrationBillsIncludedPage() - billsIncludedPage.form.submit() - assertThat(billsIncludedPage.form.getErrorMessage()).containsText("Select what you include in the rent") - } - - @Test - fun `Submitting with something else selected but no text entered returns an error`(page: Page) { - val billsIncludedPage = navigator.skipToPropertyRegistrationBillsIncludedPage() - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.selectSomethingElseCheckbox() - billsIncludedPage.form.submit() - assertThat(billsIncludedPage.form.getErrorMessage()).containsText("Enter the bills and services you include in the rent") - } - - @Test - fun `Submitting with a very long something else text returns an error`(page: Page) { - val billsIncludedPage = navigator.skipToPropertyRegistrationBillsIncludedPage() - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.selectSomethingElseCheckbox() - val aVeryLongString = - "This string is very long, so long that it is not feasible that it is a real description " + - "- therefore if it is submitted there will in fact be an error rather than a successful submission." + - " It is actually quite difficult for a string to be long enough to trigger this error, because the" + - " maximum length has been selected to be permissive of descriptions we do not expect while still having " + - "a cap reachable with a little effort." - billsIncludedPage.fillCustomBills(aVeryLongString) - billsIncludedPage.form.submit() - assertThat(billsIncludedPage.form.getErrorMessage("customBillsIncluded")) - .containsText("The description of other bills and services must be 200 characters or fewer") - } - } - - @Nested - inner class FurnishedStatusStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val furnishedStatusPage = navigator.skipToPropertyRegistrationFurnishedStatusPage() - furnishedStatusPage.form.submit() - assertThat( - furnishedStatusPage.form.getErrorMessage(), - ).containsText("Select whether the property is furnished, partly furnished or unfurnished") - } - } - - @Nested - inner class RentFrequencyStep { - @Test - fun `Submitting with no rentFrequency selected returns an error`(page: Page) { - val rentFrequencyPage = navigator.skipToPropertyRegistrationRentFrequencyPage() - rentFrequencyPage.form.submit() - assertThat(rentFrequencyPage.form.getErrorMessage()).containsText("Select how often you charge rent") - } - - @Test - fun `Submitting with other rent frequency selected but no text entered returns an error`(page: Page) { - val rentFrequencyPage = navigator.skipToPropertyRegistrationRentFrequencyPage() - rentFrequencyPage.selectRentFrequency(RentFrequency.OTHER) - rentFrequencyPage.form.submit() - assertThat(rentFrequencyPage.form.getErrorMessage()).containsText("Enter how often you charge rent") - } - } - - @Nested - inner class RentAmountStep { - @Test - fun `Submitting no rentAmount returns an error`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() - rentAmountPage.form.submit() - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") - } - - @Test - fun `Submitting a rentAmount greater than two decimals returns an error`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() - rentAmountPage.submitRentAmount("400.123") - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") - } - - @Test - fun `Submitting a negative rentAmount returns an error`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() - rentAmountPage.submitRentAmount("-400.12") - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") - } - - @Test - fun `Submitting a non-numerical rentAmount returns an error`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() - rentAmountPage.submitRentAmount("not-a-number") - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") - } - - @Test - fun `Submitting a rentAmount of 10000000 or above returns an error`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() - rentAmountPage.submitRentAmount("10000000") - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") - } - - @Nested - inner class ConditionalContentPerRentFrequency { - @Test - fun `Page renders correctly for weekly rent frequency`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.WEEKLY) - BaseComponent - .assertThat(rentAmountPage.header) - .containsText("What is the weekly rent?") - BaseComponent - .assertThat(rentAmountPage.subheading) - .containsText("Weekly rent") - BaseComponent - .assertThat(rentAmountPage.billsExplanationForRentFrequency) - .containsText("The amount you enter must be the total weekly rent agreed with the tenant.") - BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() - } - - @Test - fun `Page renders correctly for four weekly rent frequency`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.FOUR_WEEKLY) - BaseComponent - .assertThat(rentAmountPage.header) - .containsText("What is the 4-weekly rent?") - BaseComponent - .assertThat(rentAmountPage.subheading) - .containsText("4-weekly rent") - BaseComponent - .assertThat(rentAmountPage.billsExplanationForRentFrequency) - .containsText("The amount you enter must be the total 4-weekly rent agreed with the tenant.") - BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() - } - - @Test - fun `Page renders correctly for monthly rent frequency`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.MONTHLY) - BaseComponent - .assertThat(rentAmountPage.header) - .containsText("What is the monthly rent?") - BaseComponent - .assertThat(rentAmountPage.subheading) - .containsText("Monthly rent") - BaseComponent - .assertThat(rentAmountPage.billsExplanationForRentFrequency) - .containsText("The amount you enter must be the total monthly rent agreed with the tenant.") - BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() - } - - @Test - fun `Page renders correctly for 'other' rent frequency`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.OTHER) - BaseComponent - .assertThat(rentAmountPage.header) - .containsText("What is the monthly rent?") - BaseComponent - .assertThat(rentAmountPage.subheading) - .containsText("Monthly rent") - BaseComponent - .assertThat(rentAmountPage.billsExplanationForRentFrequency) - .containsText("The amount you enter must be the total monthly rent agreed with the tenant.") - BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isVisible() - } - } - } - - @Nested - inner class HasJointLandlordsStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val hasJointLandlordsPage = navigator.skipToPropertyRegistrationHasJointLandlordsPage() - hasJointLandlordsPage.form.submit() - assertThat(hasJointLandlordsPage.form.getErrorMessage()) - .containsText("Select if there are any other landlords for this property") - } - - @Test - fun `The link renders correctly`(page: Page) { - val hasJointLandlordsPage = navigator.skipToPropertyRegistrationHasJointLandlordsPage() - BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("href", GOV_LEGAL_ADVICE_URL) - BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("rel", "noreferrer noopener") - BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("target", "_blank") - } - } - - @Nested - inner class ManagingJointLandlords { - @Test - fun `Submitting remove a joint landlord with no option selected returns an error`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") - - val checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - - val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.form.submit() - assertThat(removeJointLandlordPage.form.getErrorMessage()) - .containsText("Select if you want to remove this joint landlord") - } - - @Test - fun `Submitting remove a joint landlord with No selected returns to the check page without removing the landlord`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") - - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - - val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.submitDoesNotWantToProceed() - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - } - - @Test - fun `Clicking cancel returns to the check page regardless of selected remove answer`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") - - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.form.addAnotherButton.clickAndWait() - - val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - inviteAnotherJointLandlordPage.submitEmail("beta@example.com") - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - - var removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.form.areYouSureRadios.selectValue("true") - removeJointLandlordPage.cancelLink.clickAndWait() - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - - removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.form.areYouSureRadios.selectValue("false") - removeJointLandlordPage.cancelLink.clickAndWait() - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") - } - - @Test - fun `Removing joint landlords works as expected`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") - - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.form.addAnotherButton.clickAndWait() - - val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - inviteAnotherJointLandlordPage.submitEmail("beta@example.com") - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - - var removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.submitWantsToProceed() - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("beta@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - - removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.submitWantsToProceed() - - assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - } - - @Test - fun `Editing joint landlords works as expected`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") - - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.form.addAnotherButton.clickAndWait() - - var inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - inviteAnotherJointLandlordPage.submitEmail("beta@example.com") - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Change") - - inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - BaseComponent.assertThat(inviteAnotherJointLandlordPage.form.emailInput).hasValue("alpha@example.com") - inviteAnotherJointLandlordPage.submitEmail("gamma@example.com") - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("gamma@example.com") - } - - @Test - fun `Numbering on page and tables is correct`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") - - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") - assertThat(checkJointLandlordPage.summaryList.firstRow.key).containsText("Joint landlord 1") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - checkJointLandlordPage.form.addAnotherButton.clickAndWait() - - val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - inviteAnotherJointLandlordPage.submitEmail("beta@example.com") - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") - assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).key).containsText("Joint landlord 2") - assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - - val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.submitWantsToProceed() - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") - assertThat(checkJointLandlordPage.summaryList.firstRow.key).containsText("Joint landlord 1") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("beta@example.com") - } - } - - @Nested - inner class InviteJointLandlordsStep { - @Test - fun `Submitting with no email returns an error`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("") - assertThat(inviteJointLandlordsPage.form.getErrorMessage()) - .containsText("Enter an email address in the correct format, like name@example.com") - } - - @Test - fun `Submitting with an invalid email returns an error`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("not-an-email") - assertThat(inviteJointLandlordsPage.form.getErrorMessage()) - .containsText("Enter an email address in the correct format, like name@example.com") - } - } - - @Nested - inner class InviteAnotherJointLandlordsStep { - @Test - fun `Submitting with an already invited email returns an error`(page: Page) { - val alreadyInvitedEmail = "already@invited.com" - val inviteJointLandlordsPage = - navigator.skipToPropertyRegistrationInviteAnotherJointLandlordPage(mutableListOf(alreadyInvitedEmail)) - inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) - assertThat(inviteJointLandlordsPage.form.getErrorMessage()) - .containsText("You have already invited this email address") - } - - @Test - fun `Submitting with an invited email in edit mode is permitted`(page: Page) { - val alreadyInvitedEmail = "already@invited.com" - - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) - - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Change") - - val editJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - BaseComponent.assertThat(editJointLandlordPage.form.emailInput).hasValue(alreadyInvitedEmail) - inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) - - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText(alreadyInvitedEmail) - } - } - - @Nested - inner class HasGasSupplyStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage() - hasGasSupplyPage.form.submit() - assertThat( - hasGasSupplyPage.form.getErrorMessage(), - ).containsText("Select whether you have a gas supply or any gas appliances") - } - - @Test - fun `Submitting No navigates to the check you gas answers step`(page: Page) { - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage() - hasGasSupplyPage.submitHasNoGasSupply() - assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - } - } - - @Nested - inner class HasGasSafetyCertStep { - @Test - fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { - val hasGasSafetyCertPage = navigator.skipToPropertyRegistrationHasGasCertPage() - hasGasSafetyCertPage.form.submitPrimaryButton() - assertThat( - hasGasSafetyCertPage.form.getErrorMessage(), - ).containsText("Select whether you have a gas safety certificate") - } - } - - @Nested - inner class GasSafetyIssueDateStepTests { - @ParameterizedTest(name = "{0}") - @Suppress("ktlint:standard:max-line-length") - @MethodSource( - "uk.gov.communities.prsdb.webapp.testHelpers.parameterProviders.TodayOrPastDateValidationTestParameterProvider#provideInvalidDateStrings", - ) - fun `Submitting returns a corresponding error when`( - dayMonthYear: Triple, - expectedErrorMessage: String, - ) { - val (day, month, year) = dayMonthYear - val gasSafetyIssueDatePage = navigator.skipToPropertyRegistrationGasCertIssueDatePage() - gasSafetyIssueDatePage.submitDate(day, month, year) - assertThat(gasSafetyIssueDatePage.form.getErrorMessage()).containsText(expectedErrorMessage) - } - } - - @Nested - inner class CheckGasSafetyAnswersStep { - @Test - fun `No gas supply - gas supply change link navigates to has gas supply page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersNoGasSupply(), - ) - cyaPage.gasSupplySummaryList.gasSupplyRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - } - - @Test - fun `Uploaded cert - gas supply change link navigates to has gas supply page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), - ) - cyaPage.gasSupplySummaryList.gasSupplyRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - } - - @Test - fun `Uploaded cert - valid gas cert change link navigates to has gas cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), - ) - cyaPage.certSummaryList.validGasCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - } - - @Test - fun `Uploaded cert - issue date change link navigates to issue date page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), - ) - cyaPage.certSummaryList.issueDateRow.clickFirstActionLinkAndWait() - assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - } - - @Test - fun `Uploaded cert - certificate change link navigates to check uploads page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), - ) - cyaPage.certSummaryList.yourCertificateRow.clickFirstActionLinkAndWait() - assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) - } - - @Test - fun `Provide later - gas cert change link navigates to has gas cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersProvideLater(), - ) - cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - } - - @Test - fun `No cert - gas cert change link navigates to has gas cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersNoCert(), - ) - cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - } - - @Test - fun `Cert expired - gas cert change link navigates to has gas cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersCertExpired(), - ) - cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - } - } - - @Nested - inner class HasElectricalCertStep { - @Test - fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { - val hasElectricalCertPage = navigator.skipToPropertyRegistrationHasElectricalCertPage() - hasElectricalCertPage.form.submitPrimaryButton() - assertThat( - hasElectricalCertPage.form.getErrorMessage(), - ).containsText("Select which electrical safety certificate you have") - } - } - - @Nested - inner class CheckElectricalSafetyAnswersStep { - @Test - fun `Cert uploaded EIC - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } - - @Test - fun `Cert uploaded EIC - expiry date change link navigates to expiry date page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), - ) - cyaPage.summaryList.expiryDateRow.clickFirstActionLinkAndWait() - assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - } - - @Test - fun `Cert uploaded EIC - certificate change link navigates to check uploads page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), - ) - cyaPage.summaryList.yourCertificateRow.clickFirstActionLinkAndWait() - assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) - } - - @Test - fun `Cert uploaded EICR - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEicr(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } - - @Test - fun `Provide later - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersProvideLater(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } - - @Test - fun `No cert - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersNoCert(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } - - @Test - fun `Cert expired - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersCertExpired(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } - } - - @Nested - inner class ElectricalCertExpiryDateStepTests { - @ParameterizedTest(name = "{0}") - @Suppress("ktlint:standard:max-line-length") - @MethodSource( - "uk.gov.communities.prsdb.webapp.testHelpers.parameterProviders.AnyDateValidationTestParameterProvider#provideInvalidDateStrings", - ) - fun `Submitting returns a corresponding error when`( - dayMonthYear: Triple, - expectedErrorMessage: String, - ) { - val (day, month, year) = dayMonthYear - val electricalCertExpiryDatePage = navigator.skipToPropertyRegistrationElectricalCertExpiryDatePage() - electricalCertExpiryDatePage.submitDate(day, month, year) - assertThat(electricalCertExpiryDatePage.form.getErrorMessage()).containsText(expectedErrorMessage) - } - } - - @Nested - inner class HasEpcStepTests { - @Test - fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { - val hasEpcPage = navigator.skipToPropertyRegistrationHasEpcPage() - hasEpcPage.form.submitPrimaryButton() - assertThat(hasEpcPage.form.getErrorMessage()) - .containsText("Select if you have an EPC for this property") - } - } - - @Nested - inner class FindYourEpcStepTests { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() - findYourEpcPage.form.submit() - assertThat(findYourEpcPage.form.getErrorMessage()) - .containsText("Enter a certificate number") - } - } - - @Nested - inner class ConfirmEpcDetailsRetrievedByCertificateNumberStepTests { - @Test - fun `User sees a validation error when they do not select an answer`(page: Page) { - val confirmEpcDetailsPage = - navigator.skipToPropertyRegistrationConfirmEpcDetailsRetrievedByCertificateNumberPage() - confirmEpcDetailsPage.form.submit() - assertThat(confirmEpcDetailsPage.form.getErrorMessage()) - .containsText("Select if you want to use this EPC") - } - } - - @Nested - inner class IsEpcRequiredStepTests { - @Test - fun `Submitting with no option selected returns a validation error`(page: Page) { - val isEpcRequiredPage = navigator.skipToPropertyRegistrationIsEpcRequiredPage() - isEpcRequiredPage.form.submit() - assertThat(isEpcRequiredPage.form.getErrorMessage()) - .containsText("Select if an EPC is required to let this property") - } - } - - @Nested - inner class ConfirmEpcDetailsByUprnStepTests { - @Test - fun `User sees a validation error when they do not select an answer`(page: Page) { - val confirmEpcDetailsPage = - navigator.skipToPropertyRegistrationConfirmEpcDetailsByUprnPage() - confirmEpcDetailsPage.form.submit() - assertThat(confirmEpcDetailsPage.form.getErrorMessage()) - .containsText("Select if you want to use the EPC we found for your property") - } - } - - @Nested - inner class MeesExemptionStepTests { - @Test - fun `User sees a validation error when they do not select a MEES exemption reason`(page: Page) { - val meesExemptionPage = navigator.skipToPropertyRegistrationMeesExemptionPage() - - meesExemptionPage.form.submit() - - assertPageIs(page, MeesExemptionFormPagePropertyRegistration::class) - assertThat(meesExemptionPage.form.getErrorMessage()) - .containsText("Select the energy efficiency exemption you registered for this property") - } - } - - @Nested - inner class EpcExemptionStepTests { - @Test - fun `User sees a validation error when they do not select an EPC exemption reason`(page: Page) { - val epcExemptionPage = navigator.skipToPropertyRegistrationEpcExemptionPage() - - epcExemptionPage.form.submit() - - assertPageIs(page, EpcExemptionFormPagePropertyRegistration::class) - assertThat(epcExemptionPage.form.getErrorMessage()).isVisible() - } - } - - @Nested - inner class Confirmation { - @Test - fun `Navigating here with an incomplete form returns a 400 error page`(page: Page) { - navigator.navigateToPropertyRegistrationConfirmationPage() - val errorPage = assertPageIs(page, ErrorPage::class) - BaseComponent.assertThat(errorPage.heading).containsText("Sorry, there is a problem with the service") - } - } - - @Nested - inner class PropertyRegistrationStepCheckAnswers { - @Test - fun `After changing an answer, submitting a full section saves the state and returns the CYA page`(page: Page) { - var checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() - - checkAnswersPage.summaryList.ownershipRow.actions.firstActionLink - .clickAndWait() - val ownershipPage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) - - ownershipPage.submitOwnershipType(OwnershipType.LEASEHOLD) - checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - checkAnswersPage.summaryList.licensingRow.actions.firstActionLink - .clickAndWait() - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - - licensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) - val licenceNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyRegistration::class) - licenceNumberPage.submitLicenseNumber("licence number") - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - // Confirmation - verify record saved - val savedJourneyStateCaptor = captor() - verify(savedJourneyStateRepository, times(2)).save(savedJourneyStateCaptor.capture()) - val savedJourneyStateAfterOwnershipUpdate = savedJourneyStateCaptor.allValues[0] - val savedJourneyStateAfterLicensingUpdate = savedJourneyStateCaptor.allValues[1] - assertTrue(savedJourneyStateAfterOwnershipUpdate.serializedState.contains("ownershipType\":\"LEASEHOLD\"")) - assertTrue(savedJourneyStateAfterOwnershipUpdate.serializedState.contains("licensingType\":\"NO_LICENSING\"")) - assertTrue(savedJourneyStateAfterLicensingUpdate.serializedState.contains("licensingType\":\"HMO_ADDITIONAL_LICENCE\"")) - assertTrue(savedJourneyStateAfterLicensingUpdate.serializedState.contains("licenceNumber\":\"licence number\"")) - } - - @Test - fun `the gas supply change link starts a CYA sub-journey that returns to the property registration CYA on submit`(page: Page) { - val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() - checkAnswersPage.complianceSummaryList.gasSupplyRow.clickFirstActionLinkAndWait() - val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - hasGasSupplyPage.submitHasNoGasSupply() - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - } - - @Test - fun `the electrical certificate change link navigates to the has electrical certificate page`(page: Page) { - val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() - checkAnswersPage.complianceSummaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } - - @Test - fun `the EPC change link takes the user to the confirm epc step if epc is found by uprn`(page: Page) { - whenever(epcRegisterClient.getByUprn(PropertyRegistrationJourneyTests.uprnForSelectedAddress)) - .thenReturn(MockEpcData.createEpcRegisterClientEpcFoundResponse()) - - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersCompliantEpc(), - ) - - cyaPage.epcCard - .getAction("Change") - .link - .clickAndWait() - assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) - } - - @Test - fun `the EPC change link takes the user to the has epc step if epc is found by certificate number`(page: Page) { - whenever(epcRegisterClient.getByUprn(PropertyRegistrationJourneyTests.uprnForSelectedAddress)) - .thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckAnswersEpcFoundByCertificateNumber(), - ) - cyaPage.epcCard - .getAction("Change") - .link - .clickAndWait() - assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - } - - @Test - fun `the licensing number change link navigates to the licensing page`(page: Page) { - val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPageWithSelectiveLicence() - checkAnswersPage.summaryList.licensingNumberRow.clickFirstActionLinkAndWait() - val selectiveLicencePage = assertPageIs(page, SelectiveLicenceFormPagePropertyRegistration::class) - selectiveLicencePage.submitLicenseNumber("SL-99999") - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - } - } - - @Nested - inner class EpcInDateAtStartOfTenancyCheckStep { - @Test - fun `Submitting with no option selected returns an error`() { - val epcInDateAtStartOfTenancyCheckPage = navigator.skipToPropertyRegistrationEpcInDateAtStartOfTenancyCheckPage() - epcInDateAtStartOfTenancyCheckPage.form.submit() - assertThat(epcInDateAtStartOfTenancyCheckPage.form.getErrorMessage()) - .containsText("Select if the EPC was still in date when the current tenancy began") - } - - @Test - fun `Page displays the EPC expiry date in the body text and Yes radio hint`() { - val epcInDateAtStartOfTenancyCheckPage = navigator.skipToPropertyRegistrationEpcInDateAtStartOfTenancyCheckPage() - assertThat(epcInDateAtStartOfTenancyCheckPage.bodyParagraph).containsText("5 January 2022") - assertThat(epcInDateAtStartOfTenancyCheckPage.form.yesHint).containsText("5 January 2022") - } - } - - @Nested - inner class HasMeesExemptionStep { - @Test - fun `Submitting with no option selected returns an error`() { - val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() - hasMeesExemptionPage.form.submit() - assertThat(hasMeesExemptionPage.form.getErrorMessage()) - .containsText("Select if you have a registered energy efficiency exemption for this property") - } - } - - @Nested - inner class EpcMissingStep { - @Test - fun `The page renders the occupied variant for an occupied property`(page: Page) { - val epcMissingPage = navigator.skipToPropertyRegistrationEpcMissingPage(propertyIsOccupied = true) - BaseComponent.assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - BaseComponent.assertThat(epcMissingPage.warning).isVisible() - BaseComponent.assertThat(epcMissingPage.continueAnywayButton).hasText("Continue anyway") - } - - @Test - fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { - val epcMissingPage = navigator.skipToPropertyRegistrationEpcMissingPage(propertyIsOccupied = false) - BaseComponent.assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - BaseComponent.assertThat(epcMissingPage.warning).isHidden() - BaseComponent.assertThat(epcMissingPage.continueButton).hasText("Continue") - } - } - - @Nested - inner class EpcExpiredStep { - @Test - fun `The page renders the occupied variant for an occupied property`(page: Page) { - val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = true) - BaseComponent.assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") - BaseComponent.assertThat(epcExpiredPage.warning).isVisible() - BaseComponent.assertThat(epcExpiredPage.submitButton).hasText("Continue anyway") - } - - @Test - fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { - val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = false) - BaseComponent.assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") - BaseComponent.assertThat(epcExpiredPage.warning).isHidden() - BaseComponent.assertThat(epcExpiredPage.submitButton).hasText("Continue") - } - - @Test - fun `The expiry date is displayed in bold on the occupied variant`(page: Page) { - val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = true) - assertThat(epcExpiredPage.expiryDateParagraph.locator("strong")).hasText("5 January 2022") - } - - @Test - fun `The expiry date is displayed in bold on the unoccupied variant`(page: Page) { - val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = false) - assertThat(epcExpiredPage.expiryDateParagraph.locator("strong")).hasText("5 January 2022") - } - } - - @Nested - inner class LowEnergyRatingStep { - @Test - fun `The page renders the occupied variant for an occupied property`(page: Page) { - val lowEnergyRatingPage = navigator.skipToPropertyRegistrationLowEnergyRatingPage(propertyIsOccupied = true) - BaseComponent.assertThat(lowEnergyRatingPage.heading).containsText( - "This property does not meet energy efficiency requirements for letting", - ) - BaseComponent.assertThat(lowEnergyRatingPage.continueAnywayButton).containsText("Continue anyway") - } - - @Test - fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { - val lowEnergyRatingPage = navigator.skipToPropertyRegistrationLowEnergyRatingPage(propertyIsOccupied = false) - BaseComponent.assertThat(lowEnergyRatingPage.heading).containsText( - "You’ll need to get a new EPC before letting this property", - ) - BaseComponent.assertThat(lowEnergyRatingPage.continueButton).containsText("Continue") - } - } - - @Nested - inner class ProvideEpcLaterStep { - @Test - fun `The page renders the occupied variant for an occupied property`(page: Page) { - val provideEpcLaterPage = navigator.skipToPropertyRegistrationProvideEpcLaterPage(propertyIsOccupied = true) - BaseComponent.assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") - BaseComponent.assertThat(provideEpcLaterPage.insetText).containsText( - "To keep the property registered, we need all its compliance certificates within 28 days.", + @Test + fun `Shows hasEpc and isEpcRequired rows with council inset for occupied property with no EPC that is required`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersNoEpcOccupiedNotExempt(), ) - } - - @Test - fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { - val provideEpcLaterPage = navigator.skipToPropertyRegistrationProvideEpcLaterPage(propertyIsOccupied = false) - BaseComponent.assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") - BaseComponent.assertThat(provideEpcLaterPage.insetText).isHidden() - } - } - - @Nested - inner class CheckEpcAnswersStep { - @Test - fun `Shows EPC card with meets requirements inset for a compliant unexpired EPC`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersCompliantEpc(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isVisible() - assertThat(cyaPage.epcExpiredText).isHidden() - assertThat(cyaPage.lowRatingText).isHidden() - assertThat(cyaPage.lowRatingOccupiedInset).isHidden() - assertThat(cyaPage.occupiedNoEpcInset).isHidden() - } - - @Test - fun `Shows EPC card and MEES exemption rows for an unexpired EPC with low rating and exemption`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingWithExemption(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.lowRatingText).isVisible() - assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("Yes") - assertThat(cyaPage.rows.meesExemptionRow.value).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - assertThat(cyaPage.lowRatingOccupiedInset).isHidden() - } - - @Test - fun `Shows EPC card, expired text, tenancy check row, and meets requirements inset for expired but valid EPC`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcInDateAtTenancyStart(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.epcExpiredText).isVisible() - assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") - assertThat(cyaPage.meetsRequirementsInset).isVisible() - assertThat(cyaPage.lowRatingText).isHidden() - } - @Test - fun `Shows EPC card, expired text, tenancy check, low rating text, and MEES rows for expired EPC with low rating and exemption`( - page: Page, - ) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcLowRatingWithExemption(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.epcExpiredText).isVisible() - assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") - assertThat(cyaPage.lowRatingText).isVisible() - assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("Yes") - assertThat(cyaPage.rows.meesExemptionRow.value).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - } - - @Test - fun `Shows hasEpc row with occupied provide-later text for occupied property choosing to provide EPC later`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersProvideLaterOccupied(), - ) - - assertThat(cyaPage.rows.hasEpcRow.value).containsText("Provide EPC details later") - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - } - - @Test - fun `Shows hasEpc row with unoccupied provide-later text for unoccupied property choosing to provide EPC later`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersProvideLaterUnoccupied(), - ) - - assertThat(cyaPage.rows.hasEpcRow.value).containsText("within 28 days of the property being occupied") - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - } - - @Suppress("ktlint:standard:max-line-length") - @Test - fun `Shows EPC card, low rating text, no exemption row, and council inset for occupied property with low rating and no MEES exemption`( - page: Page, - ) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingNoExemptionOccupied(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.lowRatingText).isVisible() - assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("No") - assertThat(cyaPage.lowRatingOccupiedInset).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - } - - @Test - fun `Shows provide EPC later row for unoccupied property with low rating and no MEES exemption`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingNoExemptionUnoccupied(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - assertThat(cyaPage.rows.hasEpcRow.value) - .containsText("Provide EPC details later (within 28 days of the property being occupied)") - assertThat(cyaPage.lowRatingText).isHidden() - assertThat(cyaPage.lowRatingOccupiedInset).isHidden() - } - - @Test - fun `Shows hasEpc, isEpcRequired, and exemption reason rows for property with no EPC that is exempt`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersNoEpcExempt(), - ) - - assertThat(cyaPage.rows.hasEpcRow.value).containsText("No") - assertThat(cyaPage.rows.isEpcRequiredRow.value).containsText("No") - assertThat(cyaPage.rows.epcExemptionRow.value).isVisible() - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - assertThat(cyaPage.occupiedNoEpcInset).isHidden() - } - - @Suppress("ktlint:standard:max-line-length") - @Test - fun `Shows EPC card, expired text, tenancy check, low rating text, no exemption row, and council inset for occupied property with expired low-rating EPC in date at tenancy start and no exemption`( - page: Page, - ) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcLowRatingNoExemptionOccupied(), - ) - - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.epcExpiredText).isVisible() - assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") - assertThat(cyaPage.lowRatingText).isVisible() - assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("No") - assertThat(cyaPage.lowRatingOccupiedInset).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - } - - @Test - fun `Shows hasEpc and isEpcRequired rows with council inset for occupied property with no EPC that is required`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersNoEpcOccupiedNotExempt(), - ) - - assertThat(cyaPage.rows.hasEpcRow.value).containsText("No") - assertThat(cyaPage.rows.isEpcRequiredRow.value).containsText("Yes") - assertThat(cyaPage.occupiedNoEpcInset).isVisible() - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - assertThat(cyaPage.rows.epcExemptionRow.key).isHidden() - } + assertThat(cyaPage.rows.hasEpcRow.value).containsText("No") + assertThat(cyaPage.rows.isEpcRequiredRow.value).containsText("Yes") + assertThat(cyaPage.occupiedNoEpcInset).isVisible() + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + assertThat(cyaPage.rows.epcExemptionRow.key).isHidden() } + } - @Nested - inner class ConfirmMissingComplianceStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val confirmPage = navigator.skipToPropertyRegistrationConfirmMissingCompliancePage() - confirmPage.form.submit() - assertThat(confirmPage.form.getErrorMessage()).containsText("Select whether you want to submit this registration") - } - - @Test - fun `Selecting no, go back redirects to the check answers page`(page: Page) { - val confirmPage = navigator.skipToPropertyRegistrationConfirmMissingCompliancePage() - confirmPage.form.radios.selectValue("false") - confirmPage.form.submit() - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - } + @Nested + inner class ConfirmMissingComplianceStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val confirmPage = navigator.skipToPropertyRegistrationConfirmMissingCompliancePage() + confirmPage.form.submit() + assertThat(confirmPage.form.getErrorMessage()).containsText("Select whether you want to submit this registration") + } + + @Test + fun `Selecting no, go back redirects to the check answers page`(page: Page) { + val confirmPage = navigator.skipToPropertyRegistrationConfirmMissingCompliancePage() + confirmPage.form.radios.selectValue("false") + confirmPage.form.submit() + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) } } } diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/pageObjects/pages/basePages/LicensingTypeFormPage.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/pageObjects/pages/basePages/LicensingTypeFormPage.kt index ed65f0e103..29efac6ef4 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/pageObjects/pages/basePages/LicensingTypeFormPage.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/pageObjects/pages/basePages/LicensingTypeFormPage.kt @@ -1,6 +1,8 @@ package uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.basePages import com.microsoft.playwright.Page +import uk.gov.communities.prsdb.webapp.constants.CONTINUE_BUTTON_ACTION_NAME +import uk.gov.communities.prsdb.webapp.constants.PROVIDE_THIS_LATER_BUTTON_ACTION_NAME import uk.gov.communities.prsdb.webapp.constants.enums.LicensingType import uk.gov.communities.prsdb.webapp.integration.pageObjects.components.FormWithSectionHeader import uk.gov.communities.prsdb.webapp.integration.pageObjects.components.Radios @@ -16,12 +18,21 @@ abstract class LicensingTypeFormPage( fun submitLicensingType(licensingType: LicensingType) { form.licensingTypeRadios.selectValue(licensingType) - form.submit() + form.submitPrimaryButton() } + fun submitProvideThisLater() = form.submitSecondaryButton() + + val provideThisLaterButton = form.provideThisLaterButton + class LicensingTypeForm( page: Page, ) : FormWithSectionHeader(page) { val licensingTypeRadios = Radios(locator) + val provideThisLaterButton = locator.locator("button[type='submit'][value='$PROVIDE_THIS_LATER_BUTTON_ACTION_NAME']") + + fun submitPrimaryButton(buttonAction: String = CONTINUE_BUTTON_ACTION_NAME) = submitSelectedButton(buttonAction) + + fun submitSecondaryButton(buttonAction: String = PROVIDE_THIS_LATER_BUTTON_ACTION_NAME) = submitSelectedButton(buttonAction) } } diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/pageObjects/pages/propertyRegistrationJourneyPages/ProvideLicensingLaterFormPagePropertyRegistration.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/pageObjects/pages/propertyRegistrationJourneyPages/ProvideLicensingLaterFormPagePropertyRegistration.kt new file mode 100644 index 0000000000..d7e9971742 --- /dev/null +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/pageObjects/pages/propertyRegistrationJourneyPages/ProvideLicensingLaterFormPagePropertyRegistration.kt @@ -0,0 +1,21 @@ +package uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.propertyRegistrationJourneyPages + +import com.microsoft.playwright.Page +import uk.gov.communities.prsdb.webapp.controllers.RegisterPropertyController +import uk.gov.communities.prsdb.webapp.integration.pageObjects.components.FormWithSectionHeader.SectionHeader +import uk.gov.communities.prsdb.webapp.integration.pageObjects.components.Heading +import uk.gov.communities.prsdb.webapp.integration.pageObjects.components.InsetText +import uk.gov.communities.prsdb.webapp.integration.pageObjects.components.PostForm +import uk.gov.communities.prsdb.webapp.integration.pageObjects.pages.basePages.BasePage +import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.ProvideLicensingLaterStep + +class ProvideLicensingLaterFormPagePropertyRegistration( + page: Page, +) : BasePage(page, "${RegisterPropertyController.PROPERTY_REGISTRATION_ROUTE}/${ProvideLicensingLaterStep.ROUTE_SEGMENT}") { + val heading = Heading(page.locator("h1")) + val form = PostForm(page) + val sectionHeader = SectionHeader(page.locator("main")) + + // Only present on the occupied variant + val insetText = InsetText(page) +} From f74b0bb55a4f2dfa0761c994421cdf01d63b31d9 Mon Sep 17 00:00:00 2001 From: bnjn-mt Date: Fri, 17 Jul 2026 17:55:16 +0100 Subject: [PATCH 05/10] PDJB-990: Clean up licensing provide-later integration coverage Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../PropertyDetailsUpdateJourneyTests.kt | 1733 +++++-- .../PropertyRegistrationJourneyTests.kt | 4541 +++++++++++------ .../PropertyRegistrationSinglePageTests.kt | 4343 +++++++++++----- 3 files changed, 7108 insertions(+), 3509 deletions(-) diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyDetailsUpdateJourneyTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyDetailsUpdateJourneyTests.kt index e909325554..e2ae0d2b8e 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyDetailsUpdateJourneyTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyDetailsUpdateJourneyTests.kt @@ -2,6 +2,7 @@ package uk.gov.communities.prsdb.webapp.integration import com.microsoft.playwright.Page import com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat +import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test import uk.gov.communities.prsdb.webapp.constants.PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING @@ -47,613 +48,1251 @@ class PropertyDetailsUpdateJourneyTests : IntegrationTestWithMutableData("data-l private val urlArguments = mapOf("propertyOwnershipId" to propertyOwnershipId.toString()) @Nested - inner class OwnershipTypeUpdates { - @Test - fun `A property can have its ownership type updated`(page: Page) { - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.ownershipTypeRow.clickFirstActionLinkAndWait() - val updateOwnershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update Ownership Type page - updateOwnershipTypePage.submitOwnershipType(OwnershipType.LEASEHOLD) - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.ownershipTypeRow.value).containsText("Leasehold") - } - } - - @Nested - inner class LicenceUpdates { - @Test - fun `A property can have its licensing updated to a selective licence`(page: Page) { - val newLicenceNumber = "SL123" - - // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to selective - updateLicensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) - val updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) - val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("Selective licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("Selective licence") - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) + inner class RestructureAndSkippingEnabled { + @BeforeEach + fun enableRestructureAndSkippingFlag() { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) } - @Test - fun `A property can have its licensing updated to a HMO Mandatory licence`(page: Page) { - val newLicenceNumber = "MAND123" - - // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to HMO mandatory - updateLicensingTypePage.submitLicensingType(LicensingType.HMO_MANDATORY_LICENCE) - val updateLicenceNumberPage = assertPageIs(page, HmoMandatoryLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) - val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("HMO mandatory licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("HMO mandatory licence") - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) - } + @Nested + inner class OwnershipTypeUpdates { + @Test + fun `A property can have its ownership type updated`(page: Page) { + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.ownershipTypeRow.clickFirstActionLinkAndWait() + val updateOwnershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyDetailsUpdate::class, urlArguments) - @Test - fun `A property can have its licensing updated to a HMO additional licence`(page: Page) { - val newLicenceNumber = "ADD123" - - // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to HMO additional - updateLicensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) - val updateLicenceNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) - val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("HMO additional licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("HMO additional licence") - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) - } + // Update Ownership Type page + updateOwnershipTypePage.submitOwnershipType(OwnershipType.LEASEHOLD) + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - @Test - fun `A property can have its licensing removed`(page: Page) { - // A property ownership with an existing licence - val propertyOwnershipId = 7L - val urlArguments = mapOf("propertyOwnershipId" to propertyOwnershipId.toString()) - - // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to no licensing - updateLicensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) - val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have removed this property’s licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("None") - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("None") + // Check changes have occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.ownershipTypeRow.value).containsText("Leasehold") + } } - @Test - fun `Update licensing flow does not show provide this later action`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + @Nested + inner class LicenceUpdates { + @Test + fun `A property can have its licensing updated to a selective licence`(page: Page) { + val newLicenceNumber = "SL123" - val propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + // Details page + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - assertThat(updateLicensingTypePage.provideThisLaterButton).isHidden() - } + // Update licence to selective + updateLicensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) + val updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - @Test - fun `A property can have its licensing number updated again from the check licensing answers page`(page: Page) { - val firstNewLicenceNumber = "SL456" - val secondNewLicenceNumber = "SL789" - - // Details page - var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) - propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() - val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence to selective - updateLicensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) - var updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(firstNewLicenceNumber) - var checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Click change link for Licensing Number - checkLicensingAnswersPage.summaryList.licensingNumberRow - .clickFirstActionLinkAndWait() - updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) - - // Update licence number - updateLicenceNumberPage.submitLicenseNumber(secondNewLicenceNumber) - checkLicensingAnswersPage = - assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - - // Check licensing answers - assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("Selective licence") - assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(secondNewLicenceNumber) - checkLicensingAnswersPage.confirm() - propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - - // Check changes have occurred - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("Selective licence") - assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(secondNewLicenceNumber) - } - } + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) + val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) - @Nested - inner class TenancyAndRentalInformation { - private val occupiedPropertyOwnershipId = 1L - private val occupiedPropertyUrlArguments = mapOf("propertyOwnershipId" to occupiedPropertyOwnershipId.toString()) + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("Selective licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) - private val vacantPropertyOwnershipId = 7L - private val vacantPropertyUrlArguments = mapOf("propertyOwnershipId" to vacantPropertyOwnershipId.toString()) + // Check changes have occurred + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("Selective licence") + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) + } - @Nested - inner class OccupancyUpdates { @Test - fun `A property can have its occupancy updated from occupied to vacant`(page: Page) { + fun `A property can have its licensing updated to a HMO Mandatory licence`(page: Page) { + val newLicenceNumber = "MAND123" + // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.clickFirstActionLinkAndWait() - val updateOccupancyPage = assertPageIs(page, OccupancyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update occupancy to vacant - assertThat(updateOccupancyPage.form.fieldsetHeading).containsText("Update whether your property is occupied by tenants") - updateOccupancyPage.submitIsVacant() - val checkOccupancyAnswersPage = - assertPageIs(page, CheckOccupancyAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check occupancy answers - assertThat(checkOccupancyAnswersPage.summaryList.occupancyRow).containsText("No") - assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).isHidden() - assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).isHidden() - checkOccupancyAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to HMO mandatory + updateLicensingTypePage.submitLicensingType(LicensingType.HMO_MANDATORY_LICENCE) + val updateLicenceNumberPage = assertPageIs(page, HmoMandatoryLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) + val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("HMO mandatory licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) // Check changes have occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.value).containsText("No") + assertThat( + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value, + ).containsText("HMO mandatory licence") + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) } @Test - fun `A property can have its occupancy updated from vacant to occupied`(page: Page) { + fun `A property can have its licensing updated to a HMO additional licence`(page: Page) { + val newLicenceNumber = "ADD123" + // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(vacantPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.clickFirstActionLinkAndWait() - val updateOccupancyPage = assertPageIs(page, OccupancyFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update occupancy to occupied - assertThat(updateOccupancyPage.form.fieldsetHeading).containsText("Update whether your property is occupied by tenants") - updateOccupancyPage.submitIsOccupied() - val updateNumberOfHouseholdsPage = - assertPageIs(page, OccupancyNumberOfHouseholdsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update number of households - val newNumberOfHouseholds = 1 - assertThat(updateNumberOfHouseholdsPage.header).containsText("Update how many households live in your property") - updateNumberOfHouseholdsPage.submitNumberOfHouseholds(newNumberOfHouseholds) - val updateNumberOfPeoplePage = - assertPageIs(page, OccupancyNumberOfPeopleFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update number of people - val newNumberOfPeople = 3 - assertThat(updateNumberOfPeoplePage.header).containsText("Update how many people live in your property") - updateNumberOfPeoplePage.submitNumOfPeople(newNumberOfPeople) - val bedroomsPage = - assertPageIs(page, OccupancyNumberOfBedroomsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update number of bedrooms - val newNumberOfBedrooms = 3 - assertThat(bedroomsPage.header).containsText("Update how many bedrooms are in your property") - bedroomsPage.submitNumOfBedrooms(newNumberOfBedrooms) - val rentIncludesBillsPage = - assertPageIs(page, OccupancyRentIncludesBillsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update rent include bills - assertThat(rentIncludesBillsPage.form.fieldsetHeading).containsText("Update whether the rent includes bills") - rentIncludesBillsPage.submitIsIncluded() - val billsIncludedPage = - assertPageIs(page, OccupancyBillsIncludedFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update bills included - val expectedBillsIncluded = "Gas, Electricity, Water" - assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Update which of these you include in the rent") - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.form.submit() - val furnishedPage = - assertPageIs(page, OccupancyFurnishedStatusFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update furnished status - val expectedFurnishedStatus = "Furnished" - assertThat( - furnishedPage.form.fieldsetHeading, - ).containsText("Update is the property furnished") - furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) - val rentFrequencyPage = - assertPageIs(page, OccupancyRentFrequencyFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update rent frequency - val expectedRentFrequency = "Weekly" - assertThat(rentFrequencyPage.header).containsText("Update when you charge rent") - rentFrequencyPage.selectRentFrequency(RentFrequency.WEEKLY) - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, OccupancyRentAmountFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - - // Update rent amount - val expectedRentAmount = "£400" - assertThat(rentAmountPage.header).containsText("Update your weekly rent") - rentAmountPage.submitRentAmount("400") - val checkOccupancyAnswersPage = - assertPageIs(page, CheckOccupancyAnswersPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) - // Check occupancy answers - assertThat(checkOccupancyAnswersPage.summaryList.occupancyRow).containsText("Yes") - assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText(newNumberOfHouseholds.toString()) - assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText(newNumberOfPeople.toString()) - assertThat(checkOccupancyAnswersPage.summaryList.numberOfBedroomsRow).containsText(newNumberOfBedrooms.toString()) - assertThat(checkOccupancyAnswersPage.summaryList.rentIncludesBillsRow).containsText("Yes") - assertThat(checkOccupancyAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) - assertThat(checkOccupancyAnswersPage.summaryList.furnishedStatusRow).containsText(expectedFurnishedStatus) - assertThat(checkOccupancyAnswersPage.summaryList.rentFrequencyRow).containsText(expectedRentFrequency) - assertThat(checkOccupancyAnswersPage.summaryList.rentAmountRow).containsText(expectedRentAmount) - checkOccupancyAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, vacantPropertyUrlArguments) + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to HMO additional + updateLicensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) + val updateLicenceNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) + val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("HMO additional licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) // Check changes have occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.value).containsText("Yes") - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.value) - .containsText(newNumberOfHouseholds.toString()) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfPeopleRow.value) - .containsText(newNumberOfPeople.toString()) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) - .containsText(newNumberOfBedrooms.toString()) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value).containsText("Yes") - assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow.value).containsText(expectedBillsIncluded) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value).containsText(expectedFurnishedStatus) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.value).containsText(expectedRentFrequency) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow.value).containsText(expectedRentAmount) + assertThat( + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value, + ).containsText("HMO additional licence") + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) } - } - @Nested - inner class HouseholdsAndTenantsUpdates { @Test - fun `A property can have just their number of households and people updated`(page: Page) { + fun `A property can have its licensing removed`(page: Page) { + // A property ownership with an existing licence + val propertyOwnershipId = 7L + val urlArguments = mapOf("propertyOwnershipId" to propertyOwnershipId.toString()) + // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.clickFirstActionLinkAndWait() - val updateNumberOfHouseholdsPage = - assertPageIs(page, NumberOfHouseholdsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update number of households - val newNumberOfHouseholds = 1 - assertThat(updateNumberOfHouseholdsPage.header).containsText("Update how many households live in your property") - updateNumberOfHouseholdsPage.submitNumberOfHouseholds(newNumberOfHouseholds) - val updateNumberOfPeoplePage = - assertPageIs(page, HouseholdsNumberOfPeopleFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update number of people - val newNumberOfPeople = 3 - assertThat(updateNumberOfPeoplePage.header).containsText("Update how many people live in your property") - updateNumberOfPeoplePage.submitNumOfPeople(newNumberOfPeople) - val checkOccupancyAnswersPage = - assertPageIs(page, CheckHouseholdsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check occupancy answers - assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText(newNumberOfHouseholds.toString()) - assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText(newNumberOfPeople.toString()) - checkOccupancyAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to no licensing + updateLicensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) + val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have removed this property’s licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("None") + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) // Check changes have occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.value) - .containsText(newNumberOfHouseholds.toString()) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfPeopleRow.value) - .containsText(newNumberOfPeople.toString()) + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("None") } @Test - fun `leading zeros are stripped from households and people on the CYA page`(page: Page) { + fun `Update licensing flow does not show provide this later action`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + val propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + assertThat(updateLicensingTypePage.provideThisLaterButton).isHidden() + } + + @Test + fun `A property can have its licensing number updated again from the check licensing answers page`(page: Page) { + val firstNewLicenceNumber = "SL456" + val secondNewLicenceNumber = "SL789" + // Details page - val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.clickFirstActionLinkAndWait() - val updateNumberOfHouseholdsPage = - assertPageIs(page, NumberOfHouseholdsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Submit number of households with leading zeros - updateNumberOfHouseholdsPage.submitNumberOfHouseholds("003") - val updateNumberOfPeoplePage = - assertPageIs(page, HouseholdsNumberOfPeopleFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Submit number of people with leading zeros - updateNumberOfPeoplePage.submitNumOfPeople("007") - val checkOccupancyAnswersPage = - assertPageIs(page, CheckHouseholdsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check CYA page displays values without leading zeros - assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText("3") - assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText("7") + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to selective + updateLicensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) + var updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(firstNewLicenceNumber) + var checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Click change link for Licensing Number + checkLicensingAnswersPage.summaryList.licensingNumberRow + .clickFirstActionLinkAndWait() + updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(secondNewLicenceNumber) + checkLicensingAnswersPage = + assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("Selective licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(secondNewLicenceNumber) + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("Selective licence") + assertThat( + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value, + ).containsText(secondNewLicenceNumber) } } @Nested - inner class NumberOfBedroomsUpdates { - @Test - fun `A property can have just its number of bedrooms updated`(page: Page) { - val newNumberOfBedrooms = 4 - // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - // Assert initial number of bedrooms is not 4 - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) - .not() - .containsText(newNumberOfBedrooms.toString()) - propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.clickFirstActionLinkAndWait() - val updateNumberOfBedroomsPage = - assertPageIs(page, NumberOfBedroomsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update number of bedrooms - assertThat(updateNumberOfBedroomsPage.header).containsText("Update how many bedrooms are in your property") - updateNumberOfBedroomsPage.submitNumOfBedrooms(newNumberOfBedrooms) - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check change has occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) - .containsText(newNumberOfBedrooms.toString()) + inner class TenancyAndRentalInformation { + private val occupiedPropertyOwnershipId = 1L + private val occupiedPropertyUrlArguments = mapOf("propertyOwnershipId" to occupiedPropertyOwnershipId.toString()) + + private val vacantPropertyOwnershipId = 7L + private val vacantPropertyUrlArguments = mapOf("propertyOwnershipId" to vacantPropertyOwnershipId.toString()) + + @Nested + inner class OccupancyUpdates { + @Test + fun `A property can have its occupancy updated from occupied to vacant`(page: Page) { + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.clickFirstActionLinkAndWait() + val updateOccupancyPage = + assertPageIs(page, OccupancyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update occupancy to vacant + assertThat(updateOccupancyPage.form.fieldsetHeading).containsText("Update whether your property is occupied by tenants") + updateOccupancyPage.submitIsVacant() + val checkOccupancyAnswersPage = + assertPageIs(page, CheckOccupancyAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check occupancy answers + assertThat(checkOccupancyAnswersPage.summaryList.occupancyRow).containsText("No") + assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).isHidden() + assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).isHidden() + checkOccupancyAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check changes have occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.value).containsText("No") + } + + @Test + fun `A property can have its occupancy updated from vacant to occupied`(page: Page) { + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(vacantPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.clickFirstActionLinkAndWait() + val updateOccupancyPage = assertPageIs(page, OccupancyFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update occupancy to occupied + assertThat(updateOccupancyPage.form.fieldsetHeading).containsText("Update whether your property is occupied by tenants") + updateOccupancyPage.submitIsOccupied() + val updateNumberOfHouseholdsPage = + assertPageIs(page, OccupancyNumberOfHouseholdsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update number of households + val newNumberOfHouseholds = 1 + assertThat(updateNumberOfHouseholdsPage.header).containsText("Households in your property") + updateNumberOfHouseholdsPage.submitNumberOfHouseholds(newNumberOfHouseholds) + val updateNumberOfPeoplePage = + assertPageIs(page, OccupancyNumberOfPeopleFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update number of people + val newNumberOfPeople = 3 + assertThat(updateNumberOfPeoplePage.header).containsText("Update how many people live in your property") + updateNumberOfPeoplePage.submitNumOfPeople(newNumberOfPeople) + val bedroomsPage = + assertPageIs(page, OccupancyNumberOfBedroomsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update number of bedrooms + val newNumberOfBedrooms = 3 + assertThat(bedroomsPage.header).containsText("Update how many bedrooms are in your property") + bedroomsPage.submitNumOfBedrooms(newNumberOfBedrooms) + val rentIncludesBillsPage = + assertPageIs(page, OccupancyRentIncludesBillsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update rent include bills + assertThat(rentIncludesBillsPage.form.fieldsetHeading).containsText("Update whether the rent includes bills") + rentIncludesBillsPage.submitIsIncluded() + val billsIncludedPage = + assertPageIs(page, OccupancyBillsIncludedFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update bills included + val expectedBillsIncluded = "Gas, Electricity, Water" + assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Update which of these you include in the rent") + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.form.submit() + val furnishedPage = + assertPageIs(page, OccupancyFurnishedStatusFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update furnished status + val expectedFurnishedStatus = "Furnished" + assertThat( + furnishedPage.form.fieldsetHeading, + ).containsText("Update is the property furnished") + furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) + val rentFrequencyPage = + assertPageIs(page, OccupancyRentFrequencyFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update rent frequency + val expectedRentFrequency = "Weekly" + assertThat(rentFrequencyPage.header).containsText("Update when you charge rent") + rentFrequencyPage.selectRentFrequency(RentFrequency.WEEKLY) + rentFrequencyPage.form.submit() + val rentAmountPage = + assertPageIs(page, OccupancyRentAmountFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update rent amount + val expectedRentAmount = "£400" + assertThat(rentAmountPage.header).containsText("Update your weekly rent") + rentAmountPage.submitRentAmount("400") + val checkOccupancyAnswersPage = + assertPageIs(page, CheckOccupancyAnswersPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + // Check occupancy answers + assertThat(checkOccupancyAnswersPage.summaryList.occupancyRow).containsText("Yes") + assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText(newNumberOfHouseholds.toString()) + assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText(newNumberOfPeople.toString()) + assertThat(checkOccupancyAnswersPage.summaryList.numberOfBedroomsRow).containsText(newNumberOfBedrooms.toString()) + assertThat(checkOccupancyAnswersPage.summaryList.rentIncludesBillsRow).containsText("Yes") + assertThat(checkOccupancyAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) + assertThat(checkOccupancyAnswersPage.summaryList.furnishedStatusRow).containsText(expectedFurnishedStatus) + assertThat(checkOccupancyAnswersPage.summaryList.rentFrequencyRow).containsText(expectedRentFrequency) + assertThat(checkOccupancyAnswersPage.summaryList.rentAmountRow).containsText(expectedRentAmount) + checkOccupancyAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, vacantPropertyUrlArguments) + + // Check changes have occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.value).containsText("Yes") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.value) + .containsText(newNumberOfHouseholds.toString()) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfPeopleRow.value) + .containsText(newNumberOfPeople.toString()) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) + .containsText(newNumberOfBedrooms.toString()) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value).containsText("Yes") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow.value).containsText(expectedBillsIncluded) + assertThat( + propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value, + ).containsText(expectedFurnishedStatus) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.value).containsText(expectedRentFrequency) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow.value).containsText(expectedRentAmount) + } + } + + @Nested + inner class HouseholdsAndTenantsUpdates { + @Test + fun `A property can have just their number of households and people updated`(page: Page) { + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.clickFirstActionLinkAndWait() + val updateNumberOfHouseholdsPage = + assertPageIs(page, NumberOfHouseholdsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update number of households + val newNumberOfHouseholds = 1 + assertThat(updateNumberOfHouseholdsPage.header).containsText("Households in your property") + updateNumberOfHouseholdsPage.submitNumberOfHouseholds(newNumberOfHouseholds) + val updateNumberOfPeoplePage = + assertPageIs(page, HouseholdsNumberOfPeopleFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update number of people + val newNumberOfPeople = 3 + assertThat(updateNumberOfPeoplePage.header).containsText("Update how many people live in your property") + updateNumberOfPeoplePage.submitNumOfPeople(newNumberOfPeople) + val checkOccupancyAnswersPage = + assertPageIs(page, CheckHouseholdsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check occupancy answers + assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText(newNumberOfHouseholds.toString()) + assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText(newNumberOfPeople.toString()) + checkOccupancyAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check changes have occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.value) + .containsText(newNumberOfHouseholds.toString()) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfPeopleRow.value) + .containsText(newNumberOfPeople.toString()) + } + + @Test + fun `Leading zeros are stripped from households and people on the CYA page`(page: Page) { + // Details page + val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.clickFirstActionLinkAndWait() + val updateNumberOfHouseholdsPage = + assertPageIs(page, NumberOfHouseholdsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Submit number of households with leading zeros + updateNumberOfHouseholdsPage.submitNumberOfHouseholds("003") + val updateNumberOfPeoplePage = + assertPageIs(page, HouseholdsNumberOfPeopleFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Submit number of people with leading zeros + updateNumberOfPeoplePage.submitNumOfPeople("007") + val checkOccupancyAnswersPage = + assertPageIs(page, CheckHouseholdsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check CYA page displays values without leading zeros + assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText("3") + assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText("7") + } + } + + @Nested + inner class NumberOfBedroomsUpdates { + @Test + fun `A property can have just its number of bedrooms updated`(page: Page) { + val newNumberOfBedrooms = 4 + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + // Assert initial number of bedrooms is not 4 + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) + .not() + .containsText(newNumberOfBedrooms.toString()) + propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.clickFirstActionLinkAndWait() + val updateNumberOfBedroomsPage = + assertPageIs(page, NumberOfBedroomsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update number of bedrooms + assertThat(updateNumberOfBedroomsPage.header).containsText("Update how many bedrooms are in your property") + updateNumberOfBedroomsPage.submitNumOfBedrooms(newNumberOfBedrooms) + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check change has occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) + .containsText(newNumberOfBedrooms.toString()) + } + } + + @Nested + inner class RentIncludesBills { + @Test + fun `A property can have its rent includes bills status updated`(page: Page) { + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + // Assert initial rent includes bills status is not Yes + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) + .not() + .containsText("Yes") + propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() + val updateRentIncludesBillsPage = + assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update rent includes bills to yes + assertThat(updateRentIncludesBillsPage.form.fieldsetHeading).containsText("Update whether the rent includes bills") + updateRentIncludesBillsPage.submitIsIncluded() + val billsIncludedPage = + assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update bills included + val expectedBillsIncluded = "Gas, Electricity, Water" + assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Update which of these you include in the rent") + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.form.submit() + val checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check answers + assertThat(checkYourAnswersPage.summaryList.rentIncludesBillsRow).containsText("Yes") + assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) + checkYourAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) + .containsText("Yes") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow).containsText(expectedBillsIncluded) + } + + @Test + fun `Changing the rent includes bills status from the CYA page updates the property with the correct values`(page: Page) { + // start update journey + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() + var updateRentIncludesBillsPage = + assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + // Select yes for rent includes bills + updateRentIncludesBillsPage.submitIsIncluded() + val billsIncludedPage = + assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + // Select bills included and submit + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.form.submit() + var checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Change rent includes bills answer to no + checkYourAnswersPage.summaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() + updateRentIncludesBillsPage = + assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + updateRentIncludesBillsPage.submitIsNotIncluded() + checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Confirm answers + assertThat(checkYourAnswersPage.summaryList.rentIncludesBillsRow).containsText("No") + assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).isHidden() + checkYourAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check update is correct + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) + .containsText("No") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow).isHidden() + } + + @Test + fun `Changing the bills included answer from the CYA page updates the property with the correct values`(page: Page) { + // Start update journey and reach the CYA page with bills included set + val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() + val updateRentIncludesBillsPage = + assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + updateRentIncludesBillsPage.submitIsIncluded() + val initialBillsIncludedPage = + assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + initialBillsIncludedPage.selectGasElectricityWater() + initialBillsIncludedPage.form.submit() + var checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Click the change link on the bills included row + checkYourAnswersPage.summaryList.billsIncludedRow.clickFirstActionLinkAndWait() + val billsIncludedPage = + assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Change the selection and submit + billsIncludedPage.form.billsIncludedCheckboxes.checkCheckbox(BillsIncluded.COUNCIL_TAX.toString()) + billsIncludedPage.form.submit() + checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Confirm new value shown on CYA and persisted to property details + val expectedBillsIncluded = "Gas, Electricity, Water, Council Tax" + assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) + checkYourAnswersPage.confirm() + val updatedPropertyDetailsPage = + assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + assertThat(updatedPropertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow) + .containsText(expectedBillsIncluded) + } + } + + @Nested + inner class FurnishedStatusUpdates { + @Test + fun `A property can have just its furniture status updated`(page: Page) { + val newFurnishedStatusValue = "Partly furnished" + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + // Assert initial furnished status is not FurnishedStatus.PART_FURNISHED + assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value) + .not() + .containsText(newFurnishedStatusValue) + propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.clickFirstActionLinkAndWait() + val updateFurnishedStatusPage = + assertPageIs(page, FurnishedStatusFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update furnished status + val newFurnishedStatus = FurnishedStatus.PART_FURNISHED + assertThat(updateFurnishedStatusPage.form.fieldsetHeading) + .containsText("Update is the property furnished") + updateFurnishedStatusPage.submitFurnishedStatus(newFurnishedStatus) + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check change has occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value) + .containsText(newFurnishedStatusValue) + } + } + + @Nested + inner class RentFrequencyAndAmountUpdates { + @Test + fun `A property can have its rentFrequency and amount updated`(page: Page) { + val newRentFrequency = RentFrequency.WEEKLY + val newRentFrequencyDisplayName = "Weekly" + val newRentAmount = "200" + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + // Assert initial rent frequency is not newRentFrequency + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.value) + .not() + .containsText(newRentFrequencyDisplayName) + // Assert initial rent amount is not newRentAmount + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow.value) + .not() + .containsText(newRentAmount) + propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.clickFirstActionLinkAndWait() + val rentFrequencyPage = + assertPageIs(page, RentFrequencyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update rent frequency + assertThat(rentFrequencyPage.header).containsText("Update when you charge rent") + rentFrequencyPage.selectRentFrequency(newRentFrequency) + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update rent amount + assertThat(rentAmountPage.header).containsText("Update your weekly rent") + rentAmountPage.submitRentAmount(newRentAmount) + val checkYourAnswersPage = + assertPageIs(page, CheckRentFrequencyAndAmountAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check answers + assertThat(checkYourAnswersPage.summaryList.rentFrequencyRow).containsText(newRentFrequencyDisplayName) + assertThat(checkYourAnswersPage.summaryList.rentAmountRow).containsText(newRentAmount) + checkYourAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow).containsText(newRentFrequencyDisplayName) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow).containsText(newRentAmount) + } + + @Test + fun `Leading zeros are stripped from rent amount on the CYA page`(page: Page) { + // Details page + val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.clickFirstActionLinkAndWait() + val rentFrequencyPage = + assertPageIs(page, RentFrequencyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Submit any rent frequency + rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Submit rent amount with leading zeros + rentAmountPage.submitRentAmount("00500.50") + val checkYourAnswersPage = + assertPageIs(page, CheckRentFrequencyAndAmountAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check CYA page displays value without leading zeros + assertThat(checkYourAnswersPage.summaryList.rentAmountRow).containsText("£500.50") + } } } + } + + // TODO PDJB-1340: Remove tests when the PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING Feature Flag is removed + @Nested + inner class RestructureAndSkippingDisabled { + @BeforeEach + fun disableRestructureAndSkippingFlag() { + featureFlagManager.disableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + } @Nested - inner class RentIncludesBills { + inner class OwnershipTypeUpdates { @Test - fun `A property can have its rent includes bills status updated`(page: Page) { + fun `A property can have its ownership type updated`(page: Page) { // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - // Assert initial rent includes bills status is not Yes - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) - .not() - .containsText("Yes") - propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() - val updateRentIncludesBillsPage = - assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update rent includes bills to yes - assertThat(updateRentIncludesBillsPage.form.fieldsetHeading).containsText("Update whether the rent includes bills") - updateRentIncludesBillsPage.submitIsIncluded() - val billsIncludedPage = - assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update bills included - val expectedBillsIncluded = "Gas, Electricity, Water" - assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Update which of these you include in the rent") - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.form.submit() - val checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check answers - assertThat(checkYourAnswersPage.summaryList.rentIncludesBillsRow).containsText("Yes") - assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) - checkYourAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) - .containsText("Yes") - assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow).containsText(expectedBillsIncluded) + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.ownershipTypeRow.clickFirstActionLinkAndWait() + val updateOwnershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update Ownership Type page + updateOwnershipTypePage.submitOwnershipType(OwnershipType.LEASEHOLD) + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.ownershipTypeRow.value).containsText("Leasehold") } + } + @Nested + inner class LicenceUpdates { @Test - fun `Changing the rent includes bills status from the CYA page updates the property with the correct values`(page: Page) { - // start update journey - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() - var updateRentIncludesBillsPage = - assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - // Select yes for rent includes bills - updateRentIncludesBillsPage.submitIsIncluded() - val billsIncludedPage = - assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - // Select bills included and submit - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.form.submit() - var checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Change rent includes bills answer to no - checkYourAnswersPage.summaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() - updateRentIncludesBillsPage = - assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - updateRentIncludesBillsPage.submitIsNotIncluded() - checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Confirm answers - assertThat(checkYourAnswersPage.summaryList.rentIncludesBillsRow).containsText("No") - assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).isHidden() - checkYourAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check update is correct - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) - .containsText("No") - assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow).isHidden() + fun `A property can have its licensing updated to a selective licence`(page: Page) { + val newLicenceNumber = "SL123" + + // Details page + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to selective + updateLicensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) + val updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) + val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("Selective licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("Selective licence") + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) } @Test - fun `Changing the bills included answer from the CYA page updates the property with the correct values`(page: Page) { - // Start update journey and reach the CYA page with bills included set - val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() - val updateRentIncludesBillsPage = - assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - updateRentIncludesBillsPage.submitIsIncluded() - val initialBillsIncludedPage = - assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - initialBillsIncludedPage.selectGasElectricityWater() - initialBillsIncludedPage.form.submit() - var checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Click the change link on the bills included row - checkYourAnswersPage.summaryList.billsIncludedRow.clickFirstActionLinkAndWait() - val billsIncludedPage = - assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Change the selection and submit - billsIncludedPage.form.billsIncludedCheckboxes.checkCheckbox(BillsIncluded.COUNCIL_TAX.toString()) - billsIncludedPage.form.submit() - checkYourAnswersPage = - assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Confirm new value shown on CYA and persisted to property details - val expectedBillsIncluded = "Gas, Electricity, Water, Council Tax" - assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) - checkYourAnswersPage.confirm() - val updatedPropertyDetailsPage = - assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - assertThat(updatedPropertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow) - .containsText(expectedBillsIncluded) + fun `A property can have its licensing updated to a HMO Mandatory licence`(page: Page) { + val newLicenceNumber = "MAND123" + + // Details page + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to HMO mandatory + updateLicensingTypePage.submitLicensingType(LicensingType.HMO_MANDATORY_LICENCE) + val updateLicenceNumberPage = assertPageIs(page, HmoMandatoryLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) + val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("HMO mandatory licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat( + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value, + ).containsText("HMO mandatory licence") + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) } - } - @Nested - inner class FurnishedStatusUpdates { @Test - fun `A property can have just its furniture status updated`(page: Page) { - val newFurnishedStatusValue = "Partly furnished" + fun `A property can have its licensing updated to a HMO additional licence`(page: Page) { + val newLicenceNumber = "ADD123" + // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - // Assert initial furnished status is not FurnishedStatus.PART_FURNISHED - assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value) - .not() - .containsText(newFurnishedStatusValue) - propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.clickFirstActionLinkAndWait() - val updateFurnishedStatusPage = - assertPageIs(page, FurnishedStatusFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update furnished status - val newFurnishedStatus = FurnishedStatus.PART_FURNISHED - assertThat(updateFurnishedStatusPage.form.fieldsetHeading) - .containsText("Update is the property furnished") - updateFurnishedStatusPage.submitFurnishedStatus(newFurnishedStatus) - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - // Check change has occurred - assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value) - .containsText(newFurnishedStatusValue) + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to HMO additional + updateLicensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) + val updateLicenceNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(newLicenceNumber) + val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("HMO additional licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(newLicenceNumber) + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat( + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value, + ).containsText("HMO additional licence") + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value).containsText(newLicenceNumber) } - } - @Nested - inner class RentFrequencyAndAmountUpdates { @Test - fun `A property can have its rentFrequency and amount updated`(page: Page) { - val newRentFrequency = RentFrequency.WEEKLY - val newRentFrequencyDisplayName = "Weekly" - val newRentAmount = "200" + fun `A property can have its licensing removed`(page: Page) { + // A property ownership with an existing licence + val propertyOwnershipId = 7L + val urlArguments = mapOf("propertyOwnershipId" to propertyOwnershipId.toString()) + // Details page - var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - // Assert initial rent frequency is not newRentFrequency - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.value) - .not() - .containsText(newRentFrequencyDisplayName) - // Assert initial rent amount is not newRentAmount - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow.value) - .not() - .containsText(newRentAmount) - propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.clickFirstActionLinkAndWait() - val rentFrequencyPage = - assertPageIs(page, RentFrequencyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update rent frequency - assertThat(rentFrequencyPage.header).containsText("Update when you charge rent") - rentFrequencyPage.selectRentFrequency(newRentFrequency) - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Update rent amount - assertThat(rentAmountPage.header).containsText("Update your weekly rent") - rentAmountPage.submitRentAmount(newRentAmount) - val checkYourAnswersPage = - assertPageIs(page, CheckRentFrequencyAndAmountAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check answers - assertThat(checkYourAnswersPage.summaryList.rentFrequencyRow).containsText(newRentFrequencyDisplayName) - assertThat(checkYourAnswersPage.summaryList.rentAmountRow).containsText(newRentAmount) - checkYourAnswersPage.confirm() - propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) - - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow).containsText(newRentFrequencyDisplayName) - assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow).containsText(newRentAmount) + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to no licensing + updateLicensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) + val checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have removed this property’s licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("None") + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("None") } @Test - fun `leading zeros are stripped from rent amount on the CYA page`(page: Page) { + fun `A property can have its licensing number updated again from the check licensing answers page`(page: Page) { + val firstNewLicenceNumber = "SL456" + val secondNewLicenceNumber = "SL789" + // Details page - val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) - propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.clickFirstActionLinkAndWait() - val rentFrequencyPage = - assertPageIs(page, RentFrequencyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Submit any rent frequency - rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Submit rent amount with leading zeros - rentAmountPage.submitRentAmount("00500.50") - val checkYourAnswersPage = - assertPageIs(page, CheckRentFrequencyAndAmountAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) - - // Check CYA page displays value without leading zeros - assertThat(checkYourAnswersPage.summaryList.rentAmountRow).containsText("£500.50") + var propertyDetailsUpdatePage = navigator.goToPropertyDetailsLandlordView(propertyOwnershipId) + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.clickFirstActionLinkAndWait() + val updateLicensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence to selective + updateLicensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) + var updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(firstNewLicenceNumber) + var checkLicensingAnswersPage = assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Click change link for Licensing Number + checkLicensingAnswersPage.summaryList.licensingNumberRow + .clickFirstActionLinkAndWait() + updateLicenceNumberPage = assertPageIs(page, SelectiveLicenceFormPagePropertyDetailsUpdate::class, urlArguments) + + // Update licence number + updateLicenceNumberPage.submitLicenseNumber(secondNewLicenceNumber) + checkLicensingAnswersPage = + assertPageIs(page, CheckLicensingAnswersPagePropertyDetailsUpdate::class, urlArguments) + + // Check licensing answers + assertContains(checkLicensingAnswersPage.summaryName.getText(), "You have updated the property licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingTypeRow.value).containsText("Selective licence") + assertThat(checkLicensingAnswersPage.summaryList.licensingNumberRow.value).containsText(secondNewLicenceNumber) + checkLicensingAnswersPage.confirm() + propertyDetailsUpdatePage = assertPageIs(page, PropertyDetailsPageLandlordView::class, urlArguments) + + // Check changes have occurred + assertThat(propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingTypeRow.value).containsText("Selective licence") + assertThat( + propertyDetailsUpdatePage.propertyDetailsSummaryList.licensingNumberRow.value, + ).containsText(secondNewLicenceNumber) + } + } + + @Nested + inner class TenancyAndRentalInformation { + private val occupiedPropertyOwnershipId = 1L + private val occupiedPropertyUrlArguments = mapOf("propertyOwnershipId" to occupiedPropertyOwnershipId.toString()) + + private val vacantPropertyOwnershipId = 7L + private val vacantPropertyUrlArguments = mapOf("propertyOwnershipId" to vacantPropertyOwnershipId.toString()) + + @Nested + inner class OccupancyUpdates { + @Test + fun `A property can have its occupancy updated from occupied to vacant`(page: Page) { + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.clickFirstActionLinkAndWait() + val updateOccupancyPage = + assertPageIs(page, OccupancyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update occupancy to vacant + assertThat(updateOccupancyPage.form.fieldsetHeading).containsText("Update whether your property is occupied by tenants") + updateOccupancyPage.submitIsVacant() + val checkOccupancyAnswersPage = + assertPageIs(page, CheckOccupancyAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check occupancy answers + assertThat(checkOccupancyAnswersPage.summaryList.occupancyRow).containsText("No") + assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).isHidden() + assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).isHidden() + checkOccupancyAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check changes have occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.value).containsText("No") + } + + @Test + fun `A property can have its occupancy updated from vacant to occupied`(page: Page) { + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(vacantPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.clickFirstActionLinkAndWait() + val updateOccupancyPage = assertPageIs(page, OccupancyFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update occupancy to occupied + assertThat(updateOccupancyPage.form.fieldsetHeading).containsText("Update whether your property is occupied by tenants") + updateOccupancyPage.submitIsOccupied() + val updateNumberOfHouseholdsPage = + assertPageIs(page, OccupancyNumberOfHouseholdsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update number of households + val newNumberOfHouseholds = 1 + assertThat(updateNumberOfHouseholdsPage.header).containsText("Update how many households live in your property") + updateNumberOfHouseholdsPage.submitNumberOfHouseholds(newNumberOfHouseholds) + val updateNumberOfPeoplePage = + assertPageIs(page, OccupancyNumberOfPeopleFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update number of people + val newNumberOfPeople = 3 + assertThat(updateNumberOfPeoplePage.header).containsText("Update how many people live in your property") + updateNumberOfPeoplePage.submitNumOfPeople(newNumberOfPeople) + val bedroomsPage = + assertPageIs(page, OccupancyNumberOfBedroomsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update number of bedrooms + val newNumberOfBedrooms = 3 + assertThat(bedroomsPage.header).containsText("Update how many bedrooms are in your property") + bedroomsPage.submitNumOfBedrooms(newNumberOfBedrooms) + val rentIncludesBillsPage = + assertPageIs(page, OccupancyRentIncludesBillsFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update rent include bills + assertThat(rentIncludesBillsPage.form.fieldsetHeading).containsText("Update whether the rent includes bills") + rentIncludesBillsPage.submitIsIncluded() + val billsIncludedPage = + assertPageIs(page, OccupancyBillsIncludedFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update bills included + val expectedBillsIncluded = "Gas, Electricity, Water" + assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Update which of these you include in the rent") + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.form.submit() + val furnishedPage = + assertPageIs(page, OccupancyFurnishedStatusFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update furnished status + val expectedFurnishedStatus = "Furnished" + assertThat( + furnishedPage.form.fieldsetHeading, + ).containsText("Update is the property furnished") + furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) + val rentFrequencyPage = + assertPageIs(page, OccupancyRentFrequencyFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update rent frequency + val expectedRentFrequency = "Weekly" + assertThat(rentFrequencyPage.header).containsText("Update when you charge rent") + rentFrequencyPage.selectRentFrequency(RentFrequency.WEEKLY) + rentFrequencyPage.form.submit() + val rentAmountPage = + assertPageIs(page, OccupancyRentAmountFormPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + + // Update rent amount + val expectedRentAmount = "£400" + assertThat(rentAmountPage.header).containsText("Update your weekly rent") + rentAmountPage.submitRentAmount("400") + val checkOccupancyAnswersPage = + assertPageIs(page, CheckOccupancyAnswersPagePropertyDetailsUpdate::class, vacantPropertyUrlArguments) + // Check occupancy answers + assertThat(checkOccupancyAnswersPage.summaryList.occupancyRow).containsText("Yes") + assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText(newNumberOfHouseholds.toString()) + assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText(newNumberOfPeople.toString()) + assertThat(checkOccupancyAnswersPage.summaryList.numberOfBedroomsRow).containsText(newNumberOfBedrooms.toString()) + assertThat(checkOccupancyAnswersPage.summaryList.rentIncludesBillsRow).containsText("Yes") + assertThat(checkOccupancyAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) + assertThat(checkOccupancyAnswersPage.summaryList.furnishedStatusRow).containsText(expectedFurnishedStatus) + assertThat(checkOccupancyAnswersPage.summaryList.rentFrequencyRow).containsText(expectedRentFrequency) + assertThat(checkOccupancyAnswersPage.summaryList.rentAmountRow).containsText(expectedRentAmount) + checkOccupancyAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, vacantPropertyUrlArguments) + + // Check changes have occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.occupancyRow.value).containsText("Yes") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.value) + .containsText(newNumberOfHouseholds.toString()) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfPeopleRow.value) + .containsText(newNumberOfPeople.toString()) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) + .containsText(newNumberOfBedrooms.toString()) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value).containsText("Yes") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow.value).containsText(expectedBillsIncluded) + assertThat( + propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value, + ).containsText(expectedFurnishedStatus) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.value).containsText(expectedRentFrequency) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow.value).containsText(expectedRentAmount) + } + } + + @Nested + inner class HouseholdsAndTenantsUpdates { + @Test + fun `A property can have just their number of households and people updated`(page: Page) { + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.clickFirstActionLinkAndWait() + val updateNumberOfHouseholdsPage = + assertPageIs(page, NumberOfHouseholdsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update number of households + val newNumberOfHouseholds = 1 + assertThat(updateNumberOfHouseholdsPage.header).containsText("Update how many households live in your property") + updateNumberOfHouseholdsPage.submitNumberOfHouseholds(newNumberOfHouseholds) + val updateNumberOfPeoplePage = + assertPageIs(page, HouseholdsNumberOfPeopleFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update number of people + val newNumberOfPeople = 3 + assertThat(updateNumberOfPeoplePage.header).containsText("Update how many people live in your property") + updateNumberOfPeoplePage.submitNumOfPeople(newNumberOfPeople) + val checkOccupancyAnswersPage = + assertPageIs(page, CheckHouseholdsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check occupancy answers + assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText(newNumberOfHouseholds.toString()) + assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText(newNumberOfPeople.toString()) + checkOccupancyAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check changes have occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.value) + .containsText(newNumberOfHouseholds.toString()) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfPeopleRow.value) + .containsText(newNumberOfPeople.toString()) + } + + @Test + fun `leading zeros are stripped from households and people on the CYA page`(page: Page) { + // Details page + val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.numberOfHouseholdsRow.clickFirstActionLinkAndWait() + val updateNumberOfHouseholdsPage = + assertPageIs(page, NumberOfHouseholdsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Submit number of households with leading zeros + updateNumberOfHouseholdsPage.submitNumberOfHouseholds("003") + val updateNumberOfPeoplePage = + assertPageIs(page, HouseholdsNumberOfPeopleFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Submit number of people with leading zeros + updateNumberOfPeoplePage.submitNumOfPeople("007") + val checkOccupancyAnswersPage = + assertPageIs(page, CheckHouseholdsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check CYA page displays values without leading zeros + assertThat(checkOccupancyAnswersPage.summaryList.numberOfHouseholdsRow).containsText("3") + assertThat(checkOccupancyAnswersPage.summaryList.numberOfPeopleRow).containsText("7") + } + } + + @Nested + inner class NumberOfBedroomsUpdates { + @Test + fun `A property can have just its number of bedrooms updated`(page: Page) { + val newNumberOfBedrooms = 4 + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + // Assert initial number of bedrooms is not 4 + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) + .not() + .containsText(newNumberOfBedrooms.toString()) + propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.clickFirstActionLinkAndWait() + val updateNumberOfBedroomsPage = + assertPageIs(page, NumberOfBedroomsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update number of bedrooms + assertThat(updateNumberOfBedroomsPage.header).containsText("Update how many bedrooms are in your property") + updateNumberOfBedroomsPage.submitNumOfBedrooms(newNumberOfBedrooms) + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check change has occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.numberOfBedroomsRow.value) + .containsText(newNumberOfBedrooms.toString()) + } + } + + @Nested + inner class RentIncludesBills { + @Test + fun `A property can have its rent includes bills status updated`(page: Page) { + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + // Assert initial rent includes bills status is not Yes + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) + .not() + .containsText("Yes") + propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() + val updateRentIncludesBillsPage = + assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update rent includes bills to yes + assertThat(updateRentIncludesBillsPage.form.fieldsetHeading).containsText("Update whether the rent includes bills") + updateRentIncludesBillsPage.submitIsIncluded() + val billsIncludedPage = + assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update bills included + val expectedBillsIncluded = "Gas, Electricity, Water" + assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Update which of these you include in the rent") + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.form.submit() + val checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check answers + assertThat(checkYourAnswersPage.summaryList.rentIncludesBillsRow).containsText("Yes") + assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) + checkYourAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) + .containsText("Yes") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow).containsText(expectedBillsIncluded) + } + + @Test + fun `Changing the rent includes bills status from the CYA page updates the property with the correct values`(page: Page) { + // start update journey + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() + var updateRentIncludesBillsPage = + assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + // Select yes for rent includes bills + updateRentIncludesBillsPage.submitIsIncluded() + val billsIncludedPage = + assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + // Select bills included and submit + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.form.submit() + var checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Change rent includes bills answer to no + checkYourAnswersPage.summaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() + updateRentIncludesBillsPage = + assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + updateRentIncludesBillsPage.submitIsNotIncluded() + checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Confirm answers + assertThat(checkYourAnswersPage.summaryList.rentIncludesBillsRow).containsText("No") + assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).isHidden() + checkYourAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check update is correct + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.value) + .containsText("No") + assertThat(propertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow).isHidden() + } + + @Test + fun `Changing the bills included answer from the CYA page updates the property with the correct values`(page: Page) { + // Start update journey and reach the CYA page with bills included set + val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.rentIncludesBillsRow.clickFirstActionLinkAndWait() + val updateRentIncludesBillsPage = + assertPageIs(page, RentIncludesBillsFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + updateRentIncludesBillsPage.submitIsIncluded() + val initialBillsIncludedPage = + assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + initialBillsIncludedPage.selectGasElectricityWater() + initialBillsIncludedPage.form.submit() + var checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Click the change link on the bills included row + checkYourAnswersPage.summaryList.billsIncludedRow.clickFirstActionLinkAndWait() + val billsIncludedPage = + assertPageIs(page, BillsIncludedFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Change the selection and submit + billsIncludedPage.form.billsIncludedCheckboxes.checkCheckbox(BillsIncluded.COUNCIL_TAX.toString()) + billsIncludedPage.form.submit() + checkYourAnswersPage = + assertPageIs(page, CheckRentIncludesBillsAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Confirm new value shown on CYA and persisted to property details + val expectedBillsIncluded = "Gas, Electricity, Water, Council Tax" + assertThat(checkYourAnswersPage.summaryList.billsIncludedRow).containsText(expectedBillsIncluded) + checkYourAnswersPage.confirm() + val updatedPropertyDetailsPage = + assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + assertThat(updatedPropertyDetailsPage.propertyDetailsSummaryList.billsIncludedRow) + .containsText(expectedBillsIncluded) + } + } + + @Nested + inner class FurnishedStatusUpdates { + @Test + fun `A property can have just its furniture status updated`(page: Page) { + val newFurnishedStatusValue = "Partly furnished" + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + // Assert initial furnished status is not FurnishedStatus.PART_FURNISHED + assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value) + .not() + .containsText(newFurnishedStatusValue) + propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.clickFirstActionLinkAndWait() + val updateFurnishedStatusPage = + assertPageIs(page, FurnishedStatusFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update furnished status + val newFurnishedStatus = FurnishedStatus.PART_FURNISHED + assertThat(updateFurnishedStatusPage.form.fieldsetHeading) + .containsText("Update is the property furnished") + updateFurnishedStatusPage.submitFurnishedStatus(newFurnishedStatus) + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + // Check change has occurred + assertThat(propertyDetailsPage.propertyDetailsSummaryList.furnishedStatusRow.value) + .containsText(newFurnishedStatusValue) + } + } + + @Nested + inner class RentFrequencyAndAmountUpdates { + @Test + fun `A property can have its rentFrequency and amount updated`(page: Page) { + val newRentFrequency = RentFrequency.WEEKLY + val newRentFrequencyDisplayName = "Weekly" + val newRentAmount = "200" + // Details page + var propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + // Assert initial rent frequency is not newRentFrequency + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.value) + .not() + .containsText(newRentFrequencyDisplayName) + // Assert initial rent amount is not newRentAmount + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow.value) + .not() + .containsText(newRentAmount) + propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.clickFirstActionLinkAndWait() + val rentFrequencyPage = + assertPageIs(page, RentFrequencyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update rent frequency + assertThat(rentFrequencyPage.header).containsText("Update when you charge rent") + rentFrequencyPage.selectRentFrequency(newRentFrequency) + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Update rent amount + assertThat(rentAmountPage.header).containsText("Update your weekly rent") + rentAmountPage.submitRentAmount(newRentAmount) + val checkYourAnswersPage = + assertPageIs(page, CheckRentFrequencyAndAmountAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check answers + assertThat(checkYourAnswersPage.summaryList.rentFrequencyRow).containsText(newRentFrequencyDisplayName) + assertThat(checkYourAnswersPage.summaryList.rentAmountRow).containsText(newRentAmount) + checkYourAnswersPage.confirm() + propertyDetailsPage = assertPageIs(page, PropertyDetailsPageLandlordView::class, occupiedPropertyUrlArguments) + + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow).containsText(newRentFrequencyDisplayName) + assertThat(propertyDetailsPage.propertyDetailsSummaryList.rentAmountRow).containsText(newRentAmount) + } + + @Test + fun `leading zeros are stripped from rent amount on the CYA page`(page: Page) { + // Details page + val propertyDetailsPage = navigator.goToPropertyDetailsLandlordView(occupiedPropertyOwnershipId) + propertyDetailsPage.propertyDetailsSummaryList.rentFrequencyRow.clickFirstActionLinkAndWait() + val rentFrequencyPage = + assertPageIs(page, RentFrequencyFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Submit any rent frequency + rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Submit rent amount with leading zeros + rentAmountPage.submitRentAmount("00500.50") + val checkYourAnswersPage = + assertPageIs(page, CheckRentFrequencyAndAmountAnswersPagePropertyDetailsUpdate::class, occupiedPropertyUrlArguments) + + // Check CYA page displays value without leading zeros + assertThat(checkYourAnswersPage.summaryList.rentAmountRow).containsText("£500.50") + } } } } diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt index d28e39699b..cd44480b53 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt @@ -8,6 +8,7 @@ import kotlinx.datetime.plus import kotlinx.datetime.toJavaLocalDate import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test import org.mockito.ArgumentCaptor.captor import org.mockito.kotlin.any @@ -116,7 +117,13 @@ import kotlin.test.assertTrue class PropertyRegistrationJourneyTests : IntegrationTestWithMutableData("data-local.sql") { private val absoluteLandlordUrl = "www.prsd.gov.uk/landlord" - private val propertyRegistrationSectionHeader = "Section 1 of 2 — Add property details" + private val propertyDetailsSectionHeader = "Property details" + private val ownershipSectionHeader = "Ownership and landlords" + private val occupiedSectionHeader = "Tell us if your property’s occupied" + private val licenseSectionHeader = "Tell us if your property needs a license" + private val gasSafetyHeader = "Gas safety certificate" + private val electricalSafetyHeader = "Electrical safety certificate" + private val epcSectionHeader = "Energy performance certificate (EPC)" @MockitoSpyBean private lateinit var propertyOwnershipRepository: PropertyOwnershipRepository @@ -148,1554 +155,1622 @@ class PropertyRegistrationJourneyTests : IntegrationTestWithMutableData("data-lo whenever( absoluteUrlProvider.buildPropertyDetailsUri(any()), ).thenReturn(URI("http://localhost/property-details/1")) - // The restructure flag is enabled by default in the integration config. Existing tests exercise the - // legacy journey, so disable it here; the restructured tests re-enable it explicitly in their bodies. - featureFlagManager.disableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) } - @Test - @Suppress("ktlint:standard:max-line-length") - fun `User can navigate the whole journey if pages are correctly filled in (select address, non-custom property type, selective license, occupied, compliance certificates uploaded)`( - page: Page, - ) { - // Start page (not a journey step, but it is how the user accesses the journey) - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - assertThat(registerPropertyStartPage.heading).containsText("Register a property") - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // Task list page (part of the journey to support redirects) - taskListPage.clickRegisterTaskWithName("Property address") - val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - - // Address lookup - render page - assertThat(addressLookupPage.form.fieldsetHeading).containsText("What is the property address?") - assertThat(addressLookupPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") - val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) - - // Select address - render page - assertThat(selectAddressPage.form.fieldsetHeading).containsText("Select your address") - assertThat(selectAddressPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") - val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) - - // Verify incomplete property is created at this point - verify(landlordIncompletePropertiesRepository).save(any()) - - // Property type selection - render page - assertThat(propertyTypePage.form.fieldsetHeading).containsText("What type of property are you registering?") - assertThat(propertyTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) - val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) - - // Ownership type selection - render page - assertThat(ownershipTypePage.form.fieldsetHeading).containsText("Select the type of ownership you have for your property") - assertThat(ownershipTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - - // Licensing type - render page - assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") - assertThat(licensingTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - licensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) - val selectiveLicencePage = assertPageIs(page, SelectiveLicenceFormPagePropertyRegistration::class) - - // Selective licence - render page - assertThat(selectiveLicencePage.form.fieldsetHeading).containsText("What is your selective licence number?") - assertThat(selectiveLicencePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - selectiveLicencePage.submitLicenseNumber("licence number") - val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - - // Occupancy - render page - assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") - assertThat(occupancyPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - occupancyPage.submitIsOccupied() - val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) - - // Number of households - render page - assertThat(householdsPage.header).containsText("Households in your property") - assertThat(householdsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - householdsPage.submitNumberOfHouseholds(2) - val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) - - // Number of people - render page - assertThat(peoplePage.header).containsText("How many people live in your property?") - assertThat(peoplePage.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - peoplePage.submitNumOfPeople(2) - val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) - - // Number of bedrooms - render page - assertThat(bedroomsPage.header).containsText("How many bedrooms in your property?") - assertThat(bedroomsPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - bedroomsPage.submitNumOfBedrooms(3) - val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) - - // Does the rent include bills - render page - assertThat(rentIncludesBillsPage.form.fieldsetHeading).containsText("Does the rent include bills?") - assertThat(rentIncludesBillsPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - rentIncludesBillsPage.submitIsIncluded() - val billsIncludedPage = assertPageIs(page, BillsIncludedFormPagePropertyRegistration::class) - - // Bills included - render page - assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Which of these do you include in the rent?") - assertThat(billsIncludedPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.selectSomethingElseCheckbox() - billsIncludedPage.fillCustomBills("Dog Grooming") - billsIncludedPage.form.submit() - val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) - - // Furnished - render page - assertThat(furnishedPage.form.fieldsetHeading).containsText("Is the property furnished?") - assertThat(furnishedPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) - val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) - - // Rent frequency - render page - assertThat(rentFrequencyPage.header).containsText("When you charge rent") - assertThat(rentFrequencyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - rentFrequencyPage.selectRentFrequency(RentFrequency.OTHER) - rentFrequencyPage.fillCustomRentFrequency("Fortnightly") - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) - - // Rent amount - render page - assertThat(rentAmountPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - rentAmountPage.submitRentAmount("400") - val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - - // Has Joint Landlords - render page - assertThat(hasJointLandlordsPage.header).containsText("Invite joint landlords") - assertThat(hasJointLandlordsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - - // fill in and submit - hasJointLandlordsPage.submitHasJointLandlords() - val inviteJointLandlordPage = assertPageIs(page, InviteJointLandlordFormPagePropertyRegistration::class) - - // Invite joint landlord - render page - assertThat(inviteJointLandlordPage.heading).containsText("Invite a joint landlord to this property") - assertThat(inviteJointLandlordPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - - // fill in and submit - inviteJointLandlordPage.submitEmail("email@address.com") - var checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(checkJointLandlordsPage.summaryList.firstRow.value).containsText("email@address.com") - - // Check joint landlords - render page - checkJointLandlordsPage - .form - .addAnotherButton - .clickAndWait() - - // Invite another joint landlord - render page - val addAnotherPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - assertThat(addAnotherPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - addAnotherPage.submitEmail("email2@address.com") - - checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordsPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - - // Remove Joint Landlord - render page - val removeJointLandlordsPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordsPage.submitWantsToProceed() - - checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordsPage.form.submit() - - val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - - // Has Gas Supply - render page - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert - render page - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasGasCertPage.heading).containsText("Do you have a gas safety certificate for this property?") - hasGasCertPage.submitHasCertificate() - val gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page - assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") - gasCertIssueDatePage.submitDate(validGasSafetyCertIssueDate) - var uploadGasCertPage = assertPageIs(page, UploadGasCertFormPagePropertyRegistration::class) - - // Upload Gas Cert - render page - assertThat(uploadGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - uploadGasCertPage.uploadGasCertificate(Path.of("src/test/resources/test-files/blank.png")) - var checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) - - // Check Gas Cert Uploads - render page - assertThat(checkGasCertUploadsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(checkGasCertUploadsPage.heading).containsText("You’ve uploaded 1 file") - assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - assertEquals(checkGasCertUploadsPage.table.rows.count(), 1) - checkGasCertUploadsPage.form.addAnotherButton.clickAndWait() - uploadGasCertPage = assertPageIs(page, UploadGasCertFormPagePropertyRegistration::class) - - uploadGasCertPage.uploadGasCertificate(Path.of("src/test/resources/test-files/blank.png")) - checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) - - assertThat(checkGasCertUploadsPage.heading).containsText("You’ve uploaded 2 files") - assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - assertThat(checkGasCertUploadsPage.table.getCell(1, 0)).containsText("blank.png") - assertEquals(checkGasCertUploadsPage.table.rows.count(), 2) - - checkGasCertUploadsPage.table - .getClickableCell(0, 2) - .link - .clickAndWait() - - val removeGasCertUploadPage = assertPageIs(page, RemoveGasCertUploadFormPagePropertyRegistration::class) - - removeGasCertUploadPage.form.radios.selectValue("true") - removeGasCertUploadPage.form.submit() - - checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) - assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - - assertEquals(checkGasCertUploadsPage.table.rows.count(), 1) - checkGasCertUploadsPage.form.submit() - - // Remove Gas Cert Upload - render page - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasEic() - val electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date - render page - assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(electricalCertExpiryDatePage.heading).containsText("What’s the expiry date on the Electrical Installation Certificate?") - electricalCertExpiryDatePage.submitDate(validExpiryDate) - var uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) - - // Upload Electrical Cert - render page - assertThat(uploadElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) - var checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) - - // Check Electrical Cert Uploads - render page - assertThat(checkElectricalCertUploadsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 1) - checkElectricalCertUploadsPage.form.addAnotherButton.clickAndWait() - uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) - - uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) - checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) - assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - assertThat(checkElectricalCertUploadsPage.table.getCell(1, 0)).containsText("blank.png") - assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 2) - - checkElectricalCertUploadsPage.table - .getClickableCell(0, 2) - .link - .clickAndWait() - - val removeElectricalCertUploadPage = assertPageIs(page, RemoveElectricalCertUploadFormPagePropertyRegistration::class) - - removeElectricalCertUploadPage.form.radios.selectValue("true") - removeElectricalCertUploadPage.form.submit() - - checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) - assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") - - assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 1) - checkElectricalCertUploadsPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep being able to find an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)) - .thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - expiryDate = validExpiryDate, + @Nested + inner class RestructureAndSkippingEnabled { + @BeforeEach + fun enableRestructureAndSkippingFlag() { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + } + + @Test + @Suppress("ktlint:standard:max-line-length") + fun `User can navigate the whole journey if pages are correctly filled in (select address, non-custom property type, selective license, occupied, compliance certificates uploaded)`( + page: Page, + ) { + // Start page (not a journey step, but it is how the user accesses the journey) + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + assertThat(registerPropertyStartPage.heading).containsText("Register a property") + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // Task list page (part of the journey to support redirects) + taskListPage.clickAboutYourPropertyTaskWithName("Property details") + val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + + // Address lookup - render page + assertThat(addressLookupPage.form.fieldsetHeading).containsText("What is the property address?") + assertThat(addressLookupPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) + // fill in and submit + addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") + val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) + + // Select address - render page + assertThat(selectAddressPage.form.fieldsetHeading).containsText("Select your address") + assertThat(selectAddressPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) + // fill in and submit + selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") + val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) + + // Verify incomplete property is created at this point + verify(landlordIncompletePropertiesRepository).save(any()) + + // Property type selection - render page + assertThat(propertyTypePage.form.fieldsetHeading).containsText("What type of property are you registering?") + assertThat(propertyTypePage.form.sectionHeader).containsText(propertyDetailsSectionHeader) + // fill in and submit + propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) + val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) + + // Number of bedrooms - render page + assertThat(bedroomsPage.header).containsText("How many bedrooms in your property?") + assertThat(bedroomsPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) + bedroomsPage.submitNumOfBedrooms(3) + val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + + // Ownership type selection - render page + assertThat(ownershipTypePage.form.fieldsetHeading).containsText("Select the type of ownership you have for your property") + assertThat(ownershipTypePage.form.sectionHeader).containsText(ownershipSectionHeader) + // fill in and submit + ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) + val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + + // Has Joint Landlords - render page + assertThat(hasJointLandlordsPage.header).containsText("Invite joint landlords") + assertThat(hasJointLandlordsPage.sectionHeader).containsText(ownershipSectionHeader) + + // fill in and submit + hasJointLandlordsPage.submitHasJointLandlords() + val inviteJointLandlordPage = assertPageIs(page, InviteJointLandlordFormPagePropertyRegistration::class) + + // Invite joint landlord - render page + assertThat(inviteJointLandlordPage.heading).containsText("Invite a joint landlord to this property") + assertThat(inviteJointLandlordPage.form.sectionHeader).containsText(ownershipSectionHeader) + + // fill in and submit + inviteJointLandlordPage.submitEmail("email@address.com") + var checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordsPage.sectionHeader).containsText(ownershipSectionHeader) + assertThat(checkJointLandlordsPage.summaryList.firstRow.value).containsText("email@address.com") + + // Check joint landlords - render page + checkJointLandlordsPage + .form + .addAnotherButton + .clickAndWait() + + // Invite another joint landlord - render page + val addAnotherPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + assertThat(addAnotherPage.form.sectionHeader).containsText(ownershipSectionHeader) + addAnotherPage.submitEmail("email2@address.com") + + checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordsPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + + // Remove Joint Landlord - render page + val removeJointLandlordsPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordsPage.submitWantsToProceed() + + checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordsPage.form.submit() + val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + + // Occupancy - render page + assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") + assertThat(occupancyPage.form.sectionHeader).containsText(occupiedSectionHeader) + occupancyPage.submitIsOccupied() + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + + // Licensing type - render page + assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") + assertThat(licensingTypePage.form.sectionHeader).containsText(licenseSectionHeader) + licensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) + val selectiveLicencePage = assertPageIs(page, SelectiveLicenceFormPagePropertyRegistration::class) + + // Selective licence - render page + assertThat(selectiveLicencePage.form.fieldsetHeading).containsText("What is your selective licence number?") + assertThat(selectiveLicencePage.form.sectionHeader).containsText(licenseSectionHeader) + selectiveLicencePage.submitLicenseNumber("licence number") + + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + + // Has Gas Supply - render page + assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) + assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert - render page + assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) + assertThat(hasGasCertPage.heading).containsText("Do you have a gas safety certificate for this property?") + hasGasCertPage.submitHasCertificate() + val gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page + assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(gasSafetyHeader) + assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") + gasCertIssueDatePage.submitDate(validGasSafetyCertIssueDate) + var uploadGasCertPage = assertPageIs(page, UploadGasCertFormPagePropertyRegistration::class) + + // Upload Gas Cert - render page + assertThat(uploadGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) + uploadGasCertPage.uploadGasCertificate(Path.of("src/test/resources/test-files/blank.png")) + var checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) + + // Check Gas Cert Uploads - render page + assertThat(checkGasCertUploadsPage.sectionHeader).containsText(gasSafetyHeader) + assertThat(checkGasCertUploadsPage.heading).containsText("You’ve uploaded 1 file") + assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + assertEquals(checkGasCertUploadsPage.table.rows.count(), 1) + checkGasCertUploadsPage.form.addAnotherButton.clickAndWait() + uploadGasCertPage = assertPageIs(page, UploadGasCertFormPagePropertyRegistration::class) + + uploadGasCertPage.uploadGasCertificate(Path.of("src/test/resources/test-files/blank.png")) + checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) + + assertThat(checkGasCertUploadsPage.heading).containsText("You’ve uploaded 2 files") + assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + assertThat(checkGasCertUploadsPage.table.getCell(1, 0)).containsText("blank.png") + assertEquals(checkGasCertUploadsPage.table.rows.count(), 2) + + checkGasCertUploadsPage.table + .getClickableCell(0, 2) + .link + .clickAndWait() + + val removeGasCertUploadPage = assertPageIs(page, RemoveGasCertUploadFormPagePropertyRegistration::class) + + removeGasCertUploadPage.form.radios.selectValue("true") + removeGasCertUploadPage.form.submit() + + checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) + assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + + assertEquals(checkGasCertUploadsPage.table.rows.count(), 1) + checkGasCertUploadsPage.form.submit() + + // Remove Gas Cert Upload - render page + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.sectionHeader).isHidden() + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasEic() + val electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date - render page + assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(electricalSafetyHeader) + assertThat( + electricalCertExpiryDatePage.heading, + ).containsText("What’s the expiry date on the Electrical Installation Certificate?") + electricalCertExpiryDatePage.submitDate(validExpiryDate) + var uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) + + // Upload Electrical Cert - render page + assertThat(uploadElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) + uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) + var checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + + // Check Electrical Cert Uploads - render page + assertThat(checkElectricalCertUploadsPage.sectionHeader).containsText(electricalSafetyHeader) + assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 1) + checkElectricalCertUploadsPage.form.addAnotherButton.clickAndWait() + uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) + + uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) + checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + assertThat(checkElectricalCertUploadsPage.table.getCell(1, 0)).containsText("blank.png") + assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 2) + + checkElectricalCertUploadsPage.table + .getClickableCell(0, 2) + .link + .clickAndWait() + + val removeElectricalCertUploadPage = assertPageIs(page, RemoveElectricalCertUploadFormPagePropertyRegistration::class) + + removeElectricalCertUploadPage.form.radios.selectValue("true") + removeElectricalCertUploadPage.form.submit() + + checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + + assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 1) + checkElectricalCertUploadsPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep being able to find an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)) + .thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + expiryDate = validExpiryDate, + ), + ) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.sectionHeader).isHidden() + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // EpcLookupByUprnStep finds the EPC, so redirects to Check UPRN matched EPC + taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") + val confirmUprnMatchedEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) + + // Confirm UPRN matched EPC - submit No (don't use this EPC) + assertThat(confirmUprnMatchedEpcDetailsPage.sectionHeader).containsText(epcSectionHeader) + confirmUprnMatchedEpcDetailsPage.submitNo() + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(epcSectionHeader) + hasEpcPage.submitHasEpc() + val findYourEpcPage = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) + + // EPC Search - render page + assertThat(findYourEpcPage.form.sectionHeader).containsText(epcSectionHeader) + whenever(epcRegisterClient.getByRrn(CURRENT_EPC_CERTIFICATE_NUMBER)) + .thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + certificateNumber = CURRENT_EPC_CERTIFICATE_NUMBER, + latestCertificateNumberForThisProperty = CURRENT_EPC_CERTIFICATE_NUMBER, + expiryDate = validExpiryDate, + ), + ) + findYourEpcPage.submitCurrentEpcNumber() + val confirmEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByCertificateNumberPagePropertyRegistration::class) + + // Check Matched EPC - render page + assertThat(confirmEpcDetailsPage.sectionHeader).containsText(epcSectionHeader) + val expectedExpiryDate = + validExpiryDate + .toJavaLocalDate() + .format(DateTimeFormatter.ofPattern("d MMMM yyyy")) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.addressRow.value).containsText(MockEpcData.defaultSingleLineAddress) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.energyEfficiencyRatingRow.value).containsText("C") + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.expiryDateRow.value).containsText(expectedExpiryDate) + assertThat( + confirmEpcDetailsPage.summaryCard.summaryList.certificateNumberRow.value, + ).containsText(CURRENT_EPC_CERTIFICATE_NUMBER) + confirmEpcDetailsPage.submitYes() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.sectionHeader).isHidden() + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPageAfterEpc.clickRentedOutTaskWithName("Tenancy details") + val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) + householdsPage.submitNumberOfHouseholds(2) + val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) + peoplePage.submitNumOfPeople(2) + val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) + rentIncludesBillsPage.submitIsIncluded() + val billsIncludedPage = assertPageIs(page, BillsIncludedFormPagePropertyRegistration::class) + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.selectSomethingElseCheckbox() + billsIncludedPage.fillCustomBills("Dog Grooming") + billsIncludedPage.form.submit() + val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) + furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) + val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) + rentFrequencyPage.selectRentFrequency(RentFrequency.OTHER) + rentFrequencyPage.fillCustomRentFrequency("Fortnightly") + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) + rentAmountPage.submitRentAmount("400") + val taskListPageAfterTenancyDetails = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPageAfterTenancyDetails.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + // Check answers - render page + assertThat(checkAnswersPage.heading).containsText("Check your answers for:") + assertThat(checkAnswersPage.sectionHeader).containsText("Submit your registration") + assertThat(checkAnswersPage.complianceCertificatesHeading).isVisible() + assertThat(checkAnswersPage.gasSafetyHeading).isVisible() + assertThat(checkAnswersPage.electricalSafetyHeading).isVisible() + assertThat(checkAnswersPage.epcHeading).isVisible() + // submit + checkAnswersPage.confirm() + val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) + + // Confirmation - render page + val propertyOwnershipCaptor = captor() + verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) + val expectedPropertyRegNum = + RegistrationNumberDataModel.fromRegistrationNumber( + propertyOwnershipCaptor.value.registrationNumber, + ) + assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) + assertTrue(propertyOwnershipCaptor.value.isOccupied) + assertFalse(confirmationPage.whatYouNeedToDoNextHeading.isVisible) + assertTrue(confirmationPage.surveyLink.locator.isVisible) + assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) + + // Check confirmation email + verify(confirmationEmailSender).sendEmail( + "alex.surname@example.com", + PropertyRegistrationConfirmationEmail( + expectedPropertyRegNum.toString(), + "1 Fictional Road, FA1 1AA", + absoluteLandlordUrl, + true, + listOf("email2@address.com"), ), ) - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // EpcLookupByUprnStep finds the EPC, so redirects to Check UPRN matched EPC - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val confirmUprnMatchedEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) - - // Confirm UPRN matched EPC - submit No (don't use this EPC) - assertThat(confirmUprnMatchedEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - confirmUprnMatchedEpcDetailsPage.submitNo() - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasEpcPage.submitHasEpc() - val findYourEpcPage = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) - - // EPC Search - render page - assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - whenever(epcRegisterClient.getByRrn(CURRENT_EPC_CERTIFICATE_NUMBER)) - .thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - certificateNumber = CURRENT_EPC_CERTIFICATE_NUMBER, - latestCertificateNumberForThisProperty = CURRENT_EPC_CERTIFICATE_NUMBER, - expiryDate = validExpiryDate, + // Go to dashboard + confirmationPage.goToDashboardLink.clickAndWait() + assertPageIs(page, LandlordDashboardPage::class) + } + + @Test + @Suppress("ktlint:standard:max-line-length") + fun `User can navigate the whole journey in the enabled flow (manual address, custom property type, no license, unoccupied, no joint landlords, no certificates)`( + page: Page, + ) { + // Start page (not a journey step, but it is how the user accesses the journey) + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + assertThat(registerPropertyStartPage.heading).containsText("Register a property") + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // Task list page (part of the journey to support redirects) + taskListPage.clickAboutYourPropertyTaskWithName("Property details") + val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + + // Address lookup - render page + assertThat(addressLookupPage.form.fieldsetHeading).containsText("What is the property address?") + assertThat(addressLookupPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) + // fill in and submit + addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AB", "2") + val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) + + // Select address - render page + assertThat(selectAddressPage.form.fieldsetHeading).containsText("Select your address") + assertThat(selectAddressPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) + // fill in and submit + selectAddressPage.selectAddressAndSubmit(MANUAL_ADDRESS_CHOSEN) + val manualAddressPage = assertPageIs(page, ManualAddressFormPagePropertyRegistration::class) + + // Manual address - render page + assertThat(manualAddressPage.form.fieldsetHeading).containsText("What is the property address?") + assertThat(manualAddressPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) + // fill in and submit + manualAddressPage.submitAddress(addressLineOne = "Test address line 1", townOrCity = "Testville", postcode = "EG1 2AB") + val selectLocalCouncilPage = assertPageIs(page, SelectLocalCouncilFormPagePropertyRegistration::class) + + // Select local council - render page + assertThat(selectLocalCouncilPage.form.fieldsetHeading).containsText("What local council area is your property in?") + assertThat(selectLocalCouncilPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) + // fill in and submit + selectLocalCouncilPage.submitLocalCouncil("BATH AND NORTH EAST SOMERSET COUNCIL", "BATH AND NORTH EAST SOMERSET COUNCIL") + val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) + + // Property type selection - render page + assertThat(propertyTypePage.form.fieldsetHeading).containsText("What type of property are you registering?") + assertThat(propertyTypePage.form.sectionHeader).containsText(propertyDetailsSectionHeader) + // fill in and submit + propertyTypePage.submitCustomPropertyType("End terrace house") + val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) + + // Number of bedrooms - render page + assertThat(bedroomsPage.header).containsText("How many bedrooms in your property?") + assertThat(bedroomsPage.form.sectionHeader).containsText(propertyDetailsSectionHeader) + bedroomsPage.submitNumOfBedrooms(3) + val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + + // Ownership type selection - render page + assertThat(ownershipTypePage.form.fieldsetHeading).containsText("Select the type of ownership you have for your property") + assertThat(ownershipTypePage.form.sectionHeader).containsText(ownershipSectionHeader) + // fill in and submit + ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) + val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + + // Has Joint Landlords - render page + assertThat(hasJointLandlordsPage.header).containsText("Invite joint landlords") + assertThat(hasJointLandlordsPage.sectionHeader).containsText(ownershipSectionHeader) + + // fill in and submit + hasJointLandlordsPage.submitHasNoJointLandlords() + val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + + // Occupancy - render page + assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") + assertThat(occupancyPage.form.sectionHeader).containsText(occupiedSectionHeader) + // fill in and submit + occupancyPage.submitIsVacant() + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + + // Licensing type - render page + assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") + assertThat(licensingTypePage.form.sectionHeader).containsText(licenseSectionHeader) + // fill in and submit + licensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + + // Has Gas Supply - render page + assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) + assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert - render page + assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) + assertThat(hasGasCertPage.heading).containsText("Do you have a gas safety certificate for this property?") + hasGasCertPage.submitHasNoCertificate() + val gasCertMissingPage = assertPageIs(page, GasCertMissingFormPagePropertyRegistration::class) + + // Gas Cert Missing - render page + assertThat(gasCertMissingPage.sectionHeader).containsText(gasSafetyHeader) + assertThat(gasCertMissingPage.heading).containsText("You must get a gas safety certificate before a tenant moves in") + assertThat(gasCertMissingPage.warning).isHidden() + assertThat(gasCertMissingPage.submitButton).containsText("Continue") + gasCertMissingPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasNoCert() + val electricalCertMissingPage = assertPageIs(page, ElectricalCertMissingFormPagePropertyRegistration::class) + + // Electrical Cert Missing - render page + assertThat(electricalCertMissingPage.sectionHeader).containsText(electricalSafetyHeader) + assertThat( + electricalCertMissingPage.heading, + ).containsText("You must get an electrical safety certificate before a tenant moves in") + assertThat(electricalCertMissingPage.warning).isHidden() + assertThat(electricalCertMissingPage.submitButton).containsText("Continue") + electricalCertMissingPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // We use a manual address, uprn will be null. + // The internal EpcLookupByUprnStep at the start of the EpcTask will not find an EPC + taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(epcSectionHeader) + hasEpcPage.submitHasNoEpc() + val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) + + // Is EPC required - render page + assertThat(isEpcRequiredPage.form.sectionHeader).containsText(epcSectionHeader) + assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") + isEpcRequiredPage.submitEpcRequired() + val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) + + // EPC Missing - render page + assertThat(epcMissingPage.sectionHeader).containsText(epcSectionHeader) + assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + assertThat(epcMissingPage.continueButton).containsText("Continue") + assertThat(epcMissingPage.warning).isHidden() + epcMissingPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + // Check answers - render page + assertThat(checkAnswersPage.heading).containsText("Check your answers for:") + assertThat(checkAnswersPage.sectionHeader).containsText("Submit your registration") + // submit + checkAnswersPage.confirm() + val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) + + // Confirmation - render page + val propertyOwnershipCaptor = captor() + verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) + val expectedPropertyRegNum = + RegistrationNumberDataModel.fromRegistrationNumber( + propertyOwnershipCaptor.value.registrationNumber, + ) + assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) + assertFalse(propertyOwnershipCaptor.value.isOccupied) + assertTrue(confirmationPage.whatYouNeedToDoNextHeading.isHidden) + assertTrue(confirmationPage.surveyLink.locator.isVisible) + assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) + + // Check confirmation email + verify(confirmationEmailSender).sendEmail( + "alex.surname@example.com", + PropertyRegistrationConfirmationEmail( + expectedPropertyRegNum.toString(), + "Test address line 1, Testville, EG1 2AB", + absoluteLandlordUrl, + false, + null, ), ) - findYourEpcPage.submitCurrentEpcNumber() - val confirmEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByCertificateNumberPagePropertyRegistration::class) - - // Check Matched EPC - render page - assertThat(confirmEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - val expectedExpiryDate = - validExpiryDate - .toJavaLocalDate() - .format(DateTimeFormatter.ofPattern("d MMMM yyyy")) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.addressRow.value).containsText(MockEpcData.defaultSingleLineAddress) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.energyEfficiencyRatingRow.value).containsText("C") - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.expiryDateRow.value).containsText(expectedExpiryDate) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.certificateNumberRow.value).containsText(CURRENT_EPC_CERTIFICATE_NUMBER) - confirmEpcDetailsPage.submitYes() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - // Check answers - render page - assertThat(checkAnswersPage.heading).containsText("Check your answers for:") - assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") - assertThat(checkAnswersPage.complianceCertificatesHeading).isVisible() - assertThat(checkAnswersPage.gasSafetyHeading).isVisible() - assertThat(checkAnswersPage.electricalSafetyHeading).isVisible() - assertThat(checkAnswersPage.epcHeading).isVisible() - // submit - checkAnswersPage.confirm() - val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) - - // Confirmation - render page - val propertyOwnershipCaptor = captor() - verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) - val expectedPropertyRegNum = RegistrationNumberDataModel.fromRegistrationNumber(propertyOwnershipCaptor.value.registrationNumber) - assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) - assertTrue(propertyOwnershipCaptor.value.isOccupied) - assertFalse(confirmationPage.whatYouNeedToDoNextHeading.isVisible) - assertTrue(confirmationPage.surveyLink.locator.isVisible) - assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) - - // Check confirmation email - verify(confirmationEmailSender).sendEmail( - "alex.surname@example.com", - PropertyRegistrationConfirmationEmail( - expectedPropertyRegNum.toString(), - "1 Fictional Road, FA1 1AA", - absoluteLandlordUrl, - true, - listOf("email2@address.com"), - ), - ) - - // Go to dashboard - confirmationPage.goToDashboardLink.clickAndWait() - assertPageIs(page, LandlordDashboardPage::class) - } - - @Test - @Suppress("ktlint:standard:max-line-length") - fun `User can navigate the whole journey if pages are correctly filled in (manual address, custom property type, no license, unoccupied, no joint landlords, no certificates)`( - page: Page, - ) { - // Start page (not a journey step, but it is how the user accesses the journey) - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - assertThat(registerPropertyStartPage.heading).containsText("Register a property") - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // Task list page (part of the journey to support redirects) - taskListPage.clickRegisterTaskWithName("Property address") - val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - - // Address lookup - render page - assertThat(addressLookupPage.form.fieldsetHeading).containsText("What is the property address?") - assertThat(addressLookupPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AB", "2") - val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) - - // Select address - render page - assertThat(selectAddressPage.form.fieldsetHeading).containsText("Select your address") - assertThat(selectAddressPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - selectAddressPage.selectAddressAndSubmit(MANUAL_ADDRESS_CHOSEN) - val manualAddressPage = assertPageIs(page, ManualAddressFormPagePropertyRegistration::class) - - // Manual address - render page - assertThat(manualAddressPage.form.fieldsetHeading).containsText("What is the property address?") - assertThat(manualAddressPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - manualAddressPage.submitAddress(addressLineOne = "Test address line 1", townOrCity = "Testville", postcode = "EG1 2AB") - val selectLocalCouncilPage = assertPageIs(page, SelectLocalCouncilFormPagePropertyRegistration::class) - - // Select local council - render page - assertThat(selectLocalCouncilPage.form.fieldsetHeading).containsText("What local council area is your property in?") - assertThat(selectLocalCouncilPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - selectLocalCouncilPage.submitLocalCouncil("BATH AND NORTH EAST SOMERSET COUNCIL", "BATH AND NORTH EAST SOMERSET COUNCIL") - val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) - - // Property type selection - render page - assertThat(propertyTypePage.form.fieldsetHeading).containsText("What type of property are you registering?") - assertThat(propertyTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - propertyTypePage.submitCustomPropertyType("End terrace house") - val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) - - // Ownership type selection - render page - assertThat(ownershipTypePage.form.fieldsetHeading).containsText("Select the type of ownership you have for your property") - assertThat(ownershipTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - - // Licensing type - render page - assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") - assertThat(licensingTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - licensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) - val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - - // Occupancy - render page - assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") - assertThat(occupancyPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - // fill in and submit - occupancyPage.submitIsVacant() - val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - - // Has Joint Landlords - render page - assertThat(hasJointLandlordsPage.header).containsText("Invite joint landlords") - assertThat(hasJointLandlordsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - - // fill in and submit - hasJointLandlordsPage.submitHasNoJointLandlords() - val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - - // Has Gas Supply - render page - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert - render page - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasGasCertPage.heading).containsText("Do you have a gas safety certificate for this property?") - hasGasCertPage.submitHasNoCertificate() - val gasCertMissingPage = assertPageIs(page, GasCertMissingFormPagePropertyRegistration::class) - - // Gas Cert Missing - render page - assertThat(gasCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertMissingPage.heading).containsText("You must get a gas safety certificate before a tenant moves in") - assertThat(gasCertMissingPage.warning).isHidden() - assertThat(gasCertMissingPage.submitButton).containsText("Continue") - gasCertMissingPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasNoCert() - val electricalCertMissingPage = assertPageIs(page, ElectricalCertMissingFormPagePropertyRegistration::class) - - // Electrical Cert Missing - render page - assertThat(electricalCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(electricalCertMissingPage.heading).containsText("You must get an electrical safety certificate before a tenant moves in") - assertThat(electricalCertMissingPage.warning).isHidden() - assertThat(electricalCertMissingPage.submitButton).containsText("Continue") - electricalCertMissingPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // We use a manual address, uprn will be null. - // The internal EpcLookupByUprnStep at the start of the EpcTask will not find an EPC - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasEpcPage.submitHasNoEpc() - val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) - - // Is EPC required - render page - assertThat(isEpcRequiredPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") - isEpcRequiredPage.submitEpcRequired() - val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) - - // EPC Missing - render page - assertThat(epcMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - assertThat(epcMissingPage.continueButton).containsText("Continue") - assertThat(epcMissingPage.warning).isHidden() - epcMissingPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - // Check answers - render page - assertThat(checkAnswersPage.heading).containsText("Check your answers for:") - assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") - // submit - checkAnswersPage.confirm() - val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) - - // Confirmation - render page - val propertyOwnershipCaptor = captor() - verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) - val expectedPropertyRegNum = RegistrationNumberDataModel.fromRegistrationNumber(propertyOwnershipCaptor.value.registrationNumber) - assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) - assertFalse(propertyOwnershipCaptor.value.isOccupied) - assertTrue(confirmationPage.whatYouNeedToDoNextHeading.isHidden) - assertTrue(confirmationPage.surveyLink.locator.isVisible) - assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) - - // Check confirmation email - verify(confirmationEmailSender).sendEmail( - "alex.surname@example.com", - PropertyRegistrationConfirmationEmail( - expectedPropertyRegNum.toString(), - "Test address line 1, Testville, EG1 2AB", - absoluteLandlordUrl, - false, - null, - ), - ) - - // Go to dashboard - confirmationPage.goToDashboardLink.clickAndWait() - assertPageIs(page, LandlordDashboardPage::class) - } - @Test - fun `User can choose to provide compliance certificates later if their property is occupied`(page: Page) { - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert. Submit with no option selected - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasCertPage.submitProvideThisLater() - val provideGasCertLaterPage = assertPageIs(page, ProvideGasCertLaterFormPagePropertyRegistration::class) - - // Provide Gas Cert Later - render page - assertThat(provideGasCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(provideGasCertLaterPage.insetText).containsText("You must upload your gas safety certificate within 28 days") - provideGasCertLaterPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasElectricalCertPage.submitProvideThisLater() - val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) - - // Provide Electrical Cert Later - render page - assertThat(provideElectricalCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat( - provideElectricalCertLaterPage.insetText, - ).containsText("You must upload your electrical safety certificate within 28 days.") - provideElectricalCertLaterPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasEpcPage.submitProvideThisLater() - val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) - - // Provide EPC Later - render page - assertThat(provideEpcLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") - assertThat(provideEpcLaterPage.insetText).containsText( - "To keep the property registered, we need all its compliance certificates within 28 days.", - ) - provideEpcLaterPage.form.submit() - - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - assertPageIs(page, TaskListPagePropertyRegistration::class) - } - - @Test - fun `User can choose to provide compliance certificates later if their property is unoccupied`(page: Page) { - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = false) - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert. Submit with no option selected - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasCertPage.submitProvideThisLater() - val provideGasCertLaterPage = assertPageIs(page, ProvideGasCertLaterFormPagePropertyRegistration::class) - - // Provide Gas Cert Later - render page - assertThat(provideGasCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(provideGasCertLaterPage.insetText).isHidden() - assertTrue( - provideGasCertLaterPage.page - .content() - .contains("You must get a gas safety certificate before a tenant moves in."), - ) - provideGasCertLaterPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasElectricalCertPage.submitProvideThisLater() - val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) - - // Provide Electrical Cert Later - render page (unoccupied variant) - assertThat(provideElectricalCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(provideElectricalCertLaterPage.heading).containsText("Provide your electrical safety certificate later") - assertThat(provideElectricalCertLaterPage.insetText).isHidden() - assertTrue( - provideElectricalCertLaterPage.page - .content() - .contains("You must get an electrical safety certificate before a tenant moves in."), - ) - provideElectricalCertLaterPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasEpcPage.submitProvideThisLater() - val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) - - // Provide EPC Later - render page - assertThat(provideEpcLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") - assertThat(provideEpcLaterPage.insetText).isHidden() - provideEpcLaterPage.form.submit() - - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - assertPageIs(page, TaskListPagePropertyRegistration::class) - } - - @Test - fun `User can complete the journey with missing compliance certificates for an occupied property`(page: Page) { - // Gas supply page - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert page - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasCertPage.submitHasNoCertificate() - val gasCertMissingPage = assertPageIs(page, GasCertMissingFormPagePropertyRegistration::class) - - // Gas Cert Missing - render page - assertThat(gasCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertMissingPage.heading).containsText("You must get a valid gas safety certificate for this property") - assertThat(gasCertMissingPage.submitButton).containsText("Continue without a valid gas safety certificate") - assertThat(gasCertMissingPage.warning) - .containsText("You could face prosecution if you have tenants in a property without a gas safety certificate") - gasCertMissingPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasNoCert() - val electricalCertMissingPage = assertPageIs(page, ElectricalCertMissingFormPagePropertyRegistration::class) - - assertThat(electricalCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(electricalCertMissingPage.heading).containsText("You must get a valid electrical safety certificate for this property") - assertThat(electricalCertMissingPage.warning) - .containsText("You could face prosecution if you have tenants in a property without an electrical safety certificate.") - assertThat(electricalCertMissingPage.submitButton).containsText("Continue without a valid electrical safety certificate") - electricalCertMissingPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasEpcPage.submitHasNoEpc() - val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) - - // Is EPC required - render page - assertThat(isEpcRequiredPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") - isEpcRequiredPage.submitEpcRequired() - val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) - - // EPC Missing - render page - assertThat(epcMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - assertThat(epcMissingPage.continueAnywayButton).containsText("Continue anyway") - assertThat( - epcMissingPage.warning, - ).containsText("You can be fined for letting a property that does not meet energy efficiency requirements.") - epcMissingPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") - - // Check Answers - submit to reach Confirm Missing Compliance page - checkAnswersPage.form.submit() - val confirmMissingCompliancePage = assertPageIs(page, ConfirmMissingComplianceFormPagePropertyRegistration::class) - - // Confirm Missing Compliance - render page - assertThat(confirmMissingCompliancePage.heading).containsText("Confirm missing compliance certificates") - assertThat(confirmMissingCompliancePage.warning).isVisible() - assertThat(confirmMissingCompliancePage.form.sectionHeader).containsText("Submit registration") - - // Confirm Missing Compliance - submit - confirmMissingCompliancePage.form.radios.selectValue("true") - confirmMissingCompliancePage.form.submit() - val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) - - // Confirmation - verify record saved - val propertyOwnershipCaptor = captor() - verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) - val expectedPropertyRegNum = RegistrationNumberDataModel.fromRegistrationNumber(propertyOwnershipCaptor.value.registrationNumber) - assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) - assertTrue(confirmationPage.surveyLink.locator.isVisible) - assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) - } - - @Test - fun `User can complete the journey with expired compliance certificates for an occupied property (epc found by uprn)`(page: Page) { - // Gas supply page - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert page - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasCertPage.submitHasCertificate() - var gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page - assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") - gasCertIssueDatePage.submitDate(expiredGasSafetyCertIssueDate) - var gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) - - // Gas Cert Expired - render page then navigate to edit issue date - assertThat(gasCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertExpiredPage.mainHeading).containsText("This gas safety certificate has expired") - assertThat(gasCertExpiredPage.sectionHeading).containsText("You must get a valid gas safety certificate for this property") - assertThat(gasCertExpiredPage.warning) - .containsText("You could face prosecution if you have tenants in a property without a gas safety certificate.") - assertThat(gasCertExpiredPage.submitButton).containsText("Continue without a valid gas safety certificate") - gasCertExpiredPage.changeIssueDateLink.clickAndWait() - gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page, prepopulated with previous value, then submit again - assertThat(gasCertIssueDatePage.form.dayInput).hasValue(expiredGasSafetyCertIssueDate.dayOfMonth.toString()) - assertThat(gasCertIssueDatePage.form.monthInput).hasValue(expiredGasSafetyCertIssueDate.monthNumber.toString()) - assertThat(gasCertIssueDatePage.form.yearInput).hasValue(expiredGasSafetyCertIssueDate.year.toString()) - gasCertIssueDatePage.form.submit() - gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) - - // Back on Gas Cert Expired page - submit - gasCertExpiredPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasEic() - var electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date - render page - assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - electricalCertExpiryDatePage.submitDate(expiredExpiryDate) - var electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) - - // Electrical Cert Expired - render page then check change expiry date link - assertThat(electricalCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(electricalCertExpiredPage.warning) - .containsText("You could face prosecution if you have tenants in a property without an electrical safety certificate.") - assertThat(electricalCertExpiredPage.submitButton).containsText("Continue without a valid electrical safety certificate") - electricalCertExpiredPage.changeExpiryDateLink.clickAndWait() - electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date again - render page, prepopulated with previous value, then submit again - assertThat(electricalCertExpiryDatePage.form.dayInput).hasValue(expiredExpiryDate.dayOfMonth.toString()) - assertThat(electricalCertExpiryDatePage.form.monthInput).hasValue(expiredExpiryDate.monthNumber.toString()) - assertThat(electricalCertExpiryDatePage.form.yearInput).hasValue(expiredExpiryDate.year.toString()) - electricalCertExpiryDatePage.form.submit() - electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) - - // Back on Electrical Cert Expired page - submit - electricalCertExpiredPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep being able to find an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)) - .thenReturn( + // Go to dashboard + confirmationPage.goToDashboardLink.clickAndWait() + assertPageIs(page, LandlordDashboardPage::class) + } + + @Test + fun `User can choose to provide compliance certificates later if their property is occupied`(page: Page) { + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) + assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert. Submit with no option selected + assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) + hasGasCertPage.submitProvideThisLater() + val provideGasCertLaterPage = assertPageIs(page, ProvideGasCertLaterFormPagePropertyRegistration::class) + + // Provide Gas Cert Later - render page + assertThat(provideGasCertLaterPage.sectionHeader).containsText(gasSafetyHeader) + assertThat(provideGasCertLaterPage.insetText).containsText("You must upload your gas safety certificate within 28 days") + provideGasCertLaterPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) + hasElectricalCertPage.submitProvideThisLater() + val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) + + // Provide Electrical Cert Later - render page + assertThat(provideElectricalCertLaterPage.sectionHeader).containsText(electricalSafetyHeader) + assertThat( + provideElectricalCertLaterPage.insetText, + ).containsText("You must upload your electrical safety certificate within 28 days.") + provideElectricalCertLaterPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC + taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(epcSectionHeader) + hasEpcPage.submitProvideThisLater() + val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) + + // Provide EPC Later - render page + assertThat(provideEpcLaterPage.sectionHeader).containsText(epcSectionHeader) + assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") + assertThat(provideEpcLaterPage.insetText).containsText( + "To keep the property registered, we need all its compliance certificates within 28 days.", + ) + provideEpcLaterPage.form.submit() + + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + assertPageIs(page, TaskListPagePropertyRegistration::class) + } + + @Test + fun `User can choose to provide compliance certificates later if their property is unoccupied`(page: Page) { + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = false) + assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert. Submit with no option selected + assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) + hasGasCertPage.submitProvideThisLater() + val provideGasCertLaterPage = assertPageIs(page, ProvideGasCertLaterFormPagePropertyRegistration::class) + + // Provide Gas Cert Later - render page + assertThat(provideGasCertLaterPage.sectionHeader).containsText(gasSafetyHeader) + assertThat(provideGasCertLaterPage.insetText).isHidden() + assertTrue( + provideGasCertLaterPage.page + .content() + .contains("You must get a gas safety certificate before a tenant moves in."), + ) + provideGasCertLaterPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) + hasElectricalCertPage.submitProvideThisLater() + val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) + + // Provide Electrical Cert Later - render page (unoccupied variant) + assertThat(provideElectricalCertLaterPage.sectionHeader).containsText(electricalSafetyHeader) + assertThat(provideElectricalCertLaterPage.heading).containsText("Provide your electrical safety certificate later") + assertThat(provideElectricalCertLaterPage.insetText).isHidden() + assertTrue( + provideElectricalCertLaterPage.page + .content() + .contains("You must get an electrical safety certificate before a tenant moves in."), + ) + provideElectricalCertLaterPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC + taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(epcSectionHeader) + hasEpcPage.submitProvideThisLater() + val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) + + // Provide EPC Later - render page + assertThat(provideEpcLaterPage.sectionHeader).containsText(epcSectionHeader) + assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") + assertThat(provideEpcLaterPage.insetText).isHidden() + provideEpcLaterPage.form.submit() + + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + assertPageIs(page, TaskListPagePropertyRegistration::class) + } + + @Test + fun `User can complete the journey with missing compliance certificates for an occupied property`(page: Page) { + // Gas supply page + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) + assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert page + assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) + hasGasCertPage.submitHasNoCertificate() + val gasCertMissingPage = assertPageIs(page, GasCertMissingFormPagePropertyRegistration::class) + + // Gas Cert Missing - render page + assertThat(gasCertMissingPage.sectionHeader).containsText(gasSafetyHeader) + assertThat(gasCertMissingPage.heading).containsText("You must get a valid gas safety certificate for this property") + assertThat(gasCertMissingPage.submitButton).containsText("Continue without a valid gas safety certificate") + assertThat(gasCertMissingPage.warning) + .containsText("You could face prosecution if you have tenants in a property without a gas safety certificate") + gasCertMissingPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasNoCert() + val electricalCertMissingPage = assertPageIs(page, ElectricalCertMissingFormPagePropertyRegistration::class) + + assertThat(electricalCertMissingPage.sectionHeader).containsText(electricalSafetyHeader) + assertThat( + electricalCertMissingPage.heading, + ).containsText("You must get a valid electrical safety certificate for this property") + assertThat(electricalCertMissingPage.warning) + .containsText("You could face prosecution if you have tenants in a property without an electrical safety certificate.") + assertThat(electricalCertMissingPage.submitButton).containsText("Continue without a valid electrical safety certificate") + electricalCertMissingPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC + taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(epcSectionHeader) + hasEpcPage.submitHasNoEpc() + val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) + + // Is EPC required - render page + assertThat(isEpcRequiredPage.form.sectionHeader).containsText(epcSectionHeader) + assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") + isEpcRequiredPage.submitEpcRequired() + val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) + + // EPC Missing - render page + assertThat(epcMissingPage.sectionHeader).containsText(epcSectionHeader) + assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + assertThat(epcMissingPage.continueAnywayButton).containsText("Continue anyway") + assertThat( + epcMissingPage.warning, + ).containsText("You can be fined for letting a property that does not meet energy efficiency requirements.") + epcMissingPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + assertThat(checkAnswersPage.sectionHeader).containsText("Submit your registration") + + // Check Answers - submit to reach Confirm Missing Compliance page + checkAnswersPage.form.submit() + val confirmMissingCompliancePage = assertPageIs(page, ConfirmMissingComplianceFormPagePropertyRegistration::class) + + // Confirm Missing Compliance - render page + assertThat(confirmMissingCompliancePage.heading).containsText("Confirm missing compliance certificates") + assertThat(confirmMissingCompliancePage.warning).isVisible() + assertThat(confirmMissingCompliancePage.form.sectionHeader).containsText("Submit registration") + + // Confirm Missing Compliance - submit + confirmMissingCompliancePage.form.radios.selectValue("true") + confirmMissingCompliancePage.form.submit() + val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) + + // Confirmation - verify record saved + val propertyOwnershipCaptor = captor() + verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) + val expectedPropertyRegNum = + RegistrationNumberDataModel.fromRegistrationNumber( + propertyOwnershipCaptor.value.registrationNumber, + ) + assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) + assertTrue(confirmationPage.surveyLink.locator.isVisible) + assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) + } + + @Test + fun `User can complete the journey with expired compliance certificates for an occupied property (epc found by uprn)`(page: Page) { + // Gas supply page + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) + assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert page + assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) + hasGasCertPage.submitHasCertificate() + var gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page + assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(gasSafetyHeader) + assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") + gasCertIssueDatePage.submitDate(expiredGasSafetyCertIssueDate) + var gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) + + // Gas Cert Expired - render page then navigate to edit issue date + assertThat(gasCertExpiredPage.sectionHeader).containsText(gasSafetyHeader) + assertThat(gasCertExpiredPage.mainHeading).containsText("This gas safety certificate has expired") + assertThat(gasCertExpiredPage.sectionHeading).containsText("You must get a valid gas safety certificate for this property") + assertThat(gasCertExpiredPage.warning) + .containsText("You could face prosecution if you have tenants in a property without a gas safety certificate.") + assertThat(gasCertExpiredPage.submitButton).containsText("Continue without a valid gas safety certificate") + gasCertExpiredPage.changeIssueDateLink.clickAndWait() + gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page, prepopulated with previous value, then submit again + assertThat(gasCertIssueDatePage.form.dayInput).hasValue(expiredGasSafetyCertIssueDate.dayOfMonth.toString()) + assertThat(gasCertIssueDatePage.form.monthInput).hasValue(expiredGasSafetyCertIssueDate.monthNumber.toString()) + assertThat(gasCertIssueDatePage.form.yearInput).hasValue(expiredGasSafetyCertIssueDate.year.toString()) + gasCertIssueDatePage.form.submit() + gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) + + // Back on Gas Cert Expired page - submit + gasCertExpiredPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasEic() + var electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date - render page + assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(electricalSafetyHeader) + electricalCertExpiryDatePage.submitDate(expiredExpiryDate) + var electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) + + // Electrical Cert Expired - render page then check change expiry date link + assertThat(electricalCertExpiredPage.sectionHeader).containsText(electricalSafetyHeader) + assertThat(electricalCertExpiredPage.warning) + .containsText("You could face prosecution if you have tenants in a property without an electrical safety certificate.") + assertThat(electricalCertExpiredPage.submitButton).containsText("Continue without a valid electrical safety certificate") + electricalCertExpiredPage.changeExpiryDateLink.clickAndWait() + electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date again - render page, prepopulated with previous value, then submit again + assertThat(electricalCertExpiryDatePage.form.dayInput).hasValue(expiredExpiryDate.dayOfMonth.toString()) + assertThat(electricalCertExpiryDatePage.form.monthInput).hasValue(expiredExpiryDate.monthNumber.toString()) + assertThat(electricalCertExpiryDatePage.form.yearInput).hasValue(expiredExpiryDate.year.toString()) + electricalCertExpiryDatePage.form.submit() + electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) + + // Back on Electrical Cert Expired page - submit + electricalCertExpiredPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep being able to find an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)) + .thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + expiryDate = expiredExpiryDate, + ), + ) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // EpcLookupByUprnStep finds the EPC, so redirects to Check UPRN matched EPCe + taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") + val confirmUprnMatchedEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) + + // Check UPRN matched EPC - submit Yes (accept this expired EPC, which triggers age/rating check internally) + assertThat(confirmUprnMatchedEpcDetailsPage.sectionHeader).containsText(epcSectionHeader) + confirmUprnMatchedEpcDetailsPage.submitYes() + val epcExpiryCheckPage = assertPageIs(page, EpcInDateAtStartOfTenancyCheckPagePropertyRegistration::class) + + assertThat(epcExpiryCheckPage.form.sectionHeader).containsText(epcSectionHeader) + epcExpiryCheckPage.submitEpcExpired() + val epcExpiredPage = assertPageIs(page, EpcExpiredFormPagePropertyRegistration::class) + + // EPC Expired - occupied variant: warning visible, "Continue anyway" button + assertThat(epcExpiredPage.sectionHeader).containsText(epcSectionHeader) + assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") + assertThat(epcExpiredPage.warning).isVisible() + assertThat(epcExpiredPage.submitButton).containsText("Continue anyway") + epcExpiredPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + assertThat(checkAnswersPage.sectionHeader).containsText("Submit your registration") + } + + @Test + fun `User can complete the journey with expired compliance certificates for an unoccupied property (epc not found by uprn)`( + page: Page, + ) { + // Gas supply page + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = false) + assertThat(hasGasSupplyPage.sectionHeader).containsText(gasSafetyHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert page + assertThat(hasGasCertPage.form.sectionHeader).containsText(gasSafetyHeader) + hasGasCertPage.submitHasCertificate() + var gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page + assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(gasSafetyHeader) + assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") + gasCertIssueDatePage.submitDate(expiredGasSafetyCertIssueDate) + var gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) + + // Gas Cert Expired - render page then navigate to edit issue date + assertThat(gasCertExpiredPage.sectionHeader).containsText(gasSafetyHeader) + assertThat(gasCertExpiredPage.mainHeading).containsText("This gas safety certificate has expired") + assertThat(gasCertExpiredPage.sectionHeading).containsText("What to do next") + assertThat(gasCertExpiredPage.warning).isHidden() + assertThat(gasCertExpiredPage.submitButton).containsText("Save and continue") + gasCertExpiredPage.changeIssueDateLink.clickAndWait() + gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page, prepopulated with previous value, then submit again + assertThat(gasCertIssueDatePage.form.dayInput).hasValue(expiredGasSafetyCertIssueDate.dayOfMonth.toString()) + assertThat(gasCertIssueDatePage.form.monthInput).hasValue(expiredGasSafetyCertIssueDate.monthNumber.toString()) + assertThat(gasCertIssueDatePage.form.yearInput).hasValue(expiredGasSafetyCertIssueDate.year.toString()) + gasCertIssueDatePage.form.submit() + gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) + + // Back on Gas Cert Expired page - submit + gasCertExpiredPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRentedOutTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasEic() + var electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date - render page + assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(electricalSafetyHeader) + electricalCertExpiryDatePage.submitDate(expiredExpiryDate) + var electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) + + // Electrical Cert Expired - render page then check change expiry date link + assertThat(electricalCertExpiredPage.sectionHeader).containsText(electricalSafetyHeader) + assertThat(electricalCertExpiredPage.warning).isHidden() + assertThat(electricalCertExpiredPage.submitButton).containsText("Save and continue") + electricalCertExpiredPage.changeExpiryDateLink.clickAndWait() + electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date again - render page, prepopulated with previous value, then submit again + assertThat(electricalCertExpiryDatePage.form.dayInput).hasValue(expiredExpiryDate.dayOfMonth.toString()) + assertThat(electricalCertExpiryDatePage.form.monthInput).hasValue(expiredExpiryDate.monthNumber.toString()) + assertThat(electricalCertExpiryDatePage.form.yearInput).hasValue(expiredExpiryDate.year.toString()) + electricalCertExpiryDatePage.form.submit() + electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) + + // Back on Electrical Cert Expired page - submit + electricalCertExpiredPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC + taskListPageAfterElectricalSafety.clickRentedOutTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(epcSectionHeader) + hasEpcPage.submitHasEpc() + val findYourEpcPage = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) + + // EPC Search - render page + assertThat(findYourEpcPage.form.sectionHeader).containsText(epcSectionHeader) + whenever(epcRegisterClient.getByRrn(CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER)) + .thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + certificateNumber = CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER, + expiryDate = expiredExpiryDate, + latestCertificateNumberForThisProperty = CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER, + ), + ) + findYourEpcPage.submitCurrentEpcNumberWhichIsExpired() + val confirmEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByCertificateNumberPagePropertyRegistration::class) + + // Check Matched EPC - render page + assertThat(confirmEpcDetailsPage.sectionHeader).containsText(epcSectionHeader) + val expectedExpiryDate = + expiredExpiryDate + .toJavaLocalDate() + .format(DateTimeFormatter.ofPattern("d MMMM yyyy")) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.addressRow.value).containsText(MockEpcData.defaultSingleLineAddress) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.energyEfficiencyRatingRow.value).containsText("C") + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.expiryDateRow.value).containsText(expectedExpiryDate) + assertThat( + confirmEpcDetailsPage.summaryCard.summaryList.certificateNumberRow.value, + ).containsText(CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER) + confirmEpcDetailsPage.submitYes() + val epcExpiredPage = assertPageIs(page, EpcExpiredFormPagePropertyRegistration::class) + + // EPC Expired - unoccupied variant: no warning, "Continue" button + assertThat(epcExpiredPage.sectionHeader).containsText(epcSectionHeader) + assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") + assertThat(epcExpiredPage.warning).isHidden() + assertThat(epcExpiredPage.submitButton).containsText("Continue") + epcExpiredPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + assertThat(checkAnswersPage.sectionHeader).containsText("Submit your registration") + } + + @Test + fun `The Electrical Safety task can be completed by the user uploaded an eicr`(page: Page) { + // Skip to Has Electrical Cert page and submit "Yes" + val hasElectricalCertPage = navigator.skipToPropertyRegistrationHasElectricalCertPage() + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) + hasElectricalCertPage.submitHasEicr() + val electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date - render page + assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(electricalSafetyHeader) + assertThat( + electricalCertExpiryDatePage.heading, + ).containsText("What’s the expiry date on the Electrical Installation Condition Report?") + electricalCertExpiryDatePage.submitDate(validExpiryDate) + val uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) + + // Upload Electrical Cert - render page + assertThat(uploadElectricalCertPage.form.sectionHeader).containsText(electricalSafetyHeader) + assertThat(uploadElectricalCertPage.heading).containsText("Upload the Electrical Installation Condition Report (EICR)") + uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) + + // Check Electrical Safety Answers - EICR variant verified by heading text + } + + @Test + fun `The EPC task can be completed when FindYourEpc finds a superseded epc`(page: Page) { + // Skip to Find Your EPC page and submit "Superseded EPC Found" + val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() + assertThat(findYourEpcPage.form.sectionHeader).containsText(epcSectionHeader) + whenever(epcRegisterClient.getByRrn(SUPERSEDED_EPC_CERTIFICATE_NUMBER)).thenReturn( MockEpcData.createEpcRegisterClientEpcFoundResponse( - expiryDate = expiredExpiryDate, + certificateNumber = SUPERSEDED_EPC_CERTIFICATE_NUMBER, + expiryDate = MockEpcData.expiryDateInThePast, + latestCertificateNumberForThisProperty = CURRENT_EPC_CERTIFICATE_NUMBER, ), ) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // EpcLookupByUprnStep finds the EPC, so redirects to Check UPRN matched EPCe - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val confirmUprnMatchedEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) - - // Check UPRN matched EPC - submit Yes (accept this expired EPC, which triggers age/rating check internally) - assertThat(confirmUprnMatchedEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - confirmUprnMatchedEpcDetailsPage.submitYes() - val epcExpiryCheckPage = assertPageIs(page, EpcInDateAtStartOfTenancyCheckPagePropertyRegistration::class) - - assertThat(epcExpiryCheckPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - epcExpiryCheckPage.submitEpcExpired() - val epcExpiredPage = assertPageIs(page, EpcExpiredFormPagePropertyRegistration::class) - - // EPC Expired - occupied variant: warning visible, "Continue anyway" button - assertThat(epcExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") - assertThat(epcExpiredPage.warning).isVisible() - assertThat(epcExpiredPage.submitButton).containsText("Continue anyway") - epcExpiredPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") - } - - @Test - fun `User can complete the journey with expired compliance certificates for an unoccupied property (epc not found by uprn)`( - page: Page, - ) { - // Gas supply page - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = false) - assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasSupplyPage.submitHasGasSupply() - val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - - // Has Gas Cert page - assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasGasCertPage.submitHasCertificate() - var gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page - assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") - gasCertIssueDatePage.submitDate(expiredGasSafetyCertIssueDate) - var gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) - - // Gas Cert Expired - render page then navigate to edit issue date - assertThat(gasCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(gasCertExpiredPage.mainHeading).containsText("This gas safety certificate has expired") - assertThat(gasCertExpiredPage.sectionHeading).containsText("What to do next") - assertThat(gasCertExpiredPage.warning).isHidden() - assertThat(gasCertExpiredPage.submitButton).containsText("Save and continue") - gasCertExpiredPage.changeIssueDateLink.clickAndWait() - gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - - // Gas Cert Issue Date - render page, prepopulated with previous value, then submit again - assertThat(gasCertIssueDatePage.form.dayInput).hasValue(expiredGasSafetyCertIssueDate.dayOfMonth.toString()) - assertThat(gasCertIssueDatePage.form.monthInput).hasValue(expiredGasSafetyCertIssueDate.monthNumber.toString()) - assertThat(gasCertIssueDatePage.form.yearInput).hasValue(expiredGasSafetyCertIssueDate.year.toString()) - gasCertIssueDatePage.form.submit() - gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) - - // Back on Gas Cert Expired page - submit - gasCertExpiredPage.form.submit() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - - // Check Gas Safety Answers - render page - assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") - - checkGasSafetyAnswersPage.form.submit() - val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - - // Has Electrical Cert - render page - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") - hasElectricalCertPage.submitHasEic() - var electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date - render page - assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - electricalCertExpiryDatePage.submitDate(expiredExpiryDate) - var electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) - - // Electrical Cert Expired - render page then check change expiry date link - assertThat(electricalCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(electricalCertExpiredPage.warning).isHidden() - assertThat(electricalCertExpiredPage.submitButton).containsText("Save and continue") - electricalCertExpiredPage.changeExpiryDateLink.clickAndWait() - electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date again - render page, prepopulated with previous value, then submit again - assertThat(electricalCertExpiryDatePage.form.dayInput).hasValue(expiredExpiryDate.dayOfMonth.toString()) - assertThat(electricalCertExpiryDatePage.form.monthInput).hasValue(expiredExpiryDate.monthNumber.toString()) - assertThat(electricalCertExpiryDatePage.form.yearInput).hasValue(expiredExpiryDate.year.toString()) - electricalCertExpiryDatePage.form.submit() - electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) - - // Back on Electrical Cert Expired page - submit - electricalCertExpiredPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - - // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - // Check Electrical Safety Answers - render page - assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") - checkElectricalSafetyAnswersPage.form.submit() - val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) - - // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC - taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - - // Has EPC - render page - assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasEpcPage.submitHasEpc() - val findYourEpcPage = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) - - // EPC Search - render page - assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - whenever(epcRegisterClient.getByRrn(CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER)) - .thenReturn( + whenever(epcRegisterClient.getByRrn(CURRENT_EPC_CERTIFICATE_NUMBER)).thenReturn( MockEpcData.createEpcRegisterClientEpcFoundResponse( - certificateNumber = CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER, - expiryDate = expiredExpiryDate, - latestCertificateNumberForThisProperty = CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER, + certificateNumber = CURRENT_EPC_CERTIFICATE_NUMBER, ), ) - findYourEpcPage.submitCurrentEpcNumberWhichIsExpired() - val confirmEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByCertificateNumberPagePropertyRegistration::class) - - // Check Matched EPC - render page - assertThat(confirmEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - val expectedExpiryDate = - expiredExpiryDate - .toJavaLocalDate() - .format(DateTimeFormatter.ofPattern("d MMMM yyyy")) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.addressRow.value).containsText(MockEpcData.defaultSingleLineAddress) - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.energyEfficiencyRatingRow.value).containsText("C") - assertThat(confirmEpcDetailsPage.summaryCard.summaryList.expiryDateRow.value).containsText(expectedExpiryDate) - assertThat( - confirmEpcDetailsPage.summaryCard.summaryList.certificateNumberRow.value, - ).containsText(CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER) - confirmEpcDetailsPage.submitYes() - val epcExpiredPage = assertPageIs(page, EpcExpiredFormPagePropertyRegistration::class) - - // EPC Expired - unoccupied variant: no warning, "Continue" button - assertThat(epcExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") - assertThat(epcExpiredPage.warning).isHidden() - assertThat(epcExpiredPage.submitButton).containsText("Continue") - epcExpiredPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") - } - - @Test - fun `The Electrical Safety task can be completed by the user uploaded an eicr`(page: Page) { - // Skip to Has Electrical Cert page and submit "Yes" - val hasElectricalCertPage = navigator.skipToPropertyRegistrationHasElectricalCertPage() - assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasElectricalCertPage.submitHasEicr() - val electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) - - // Electrical Cert Expiry Date - render page - assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat( - electricalCertExpiryDatePage.heading, - ).containsText("What’s the expiry date on the Electrical Installation Condition Report?") - electricalCertExpiryDatePage.submitDate(validExpiryDate) - val uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) - - // Upload Electrical Cert - render page - assertThat(uploadElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(uploadElectricalCertPage.heading).containsText("Upload the Electrical Installation Condition Report (EICR)") - uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) - - // Check Electrical Safety Answers - EICR variant verified by heading text - } - - @Test - fun `The EPC task can be completed when FindYourEpc finds a superseded epc`(page: Page) { - // Skip to Find Your EPC page and submit "Superseded EPC Found" - val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() - assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - whenever(epcRegisterClient.getByRrn(SUPERSEDED_EPC_CERTIFICATE_NUMBER)).thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - certificateNumber = SUPERSEDED_EPC_CERTIFICATE_NUMBER, - expiryDate = MockEpcData.expiryDateInThePast, - latestCertificateNumberForThisProperty = CURRENT_EPC_CERTIFICATE_NUMBER, - ), - ) - whenever(epcRegisterClient.getByRrn(CURRENT_EPC_CERTIFICATE_NUMBER)).thenReturn( - MockEpcData.createEpcRegisterClientEpcFoundResponse( - certificateNumber = CURRENT_EPC_CERTIFICATE_NUMBER, - ), - ) - findYourEpcPage.submitSupersededEpcNumber() - val epcSupersededPage = assertPageIs(page, EpcSuperseededFormPagePropertyRegistration::class) - - // Check details of superseded and latest epc - render page - assertThat(epcSupersededPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - epcSupersededPage.submitContinueWithLatest() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - assertPageIs(page, TaskListPagePropertyRegistration::class) - } - - @Test - fun `The EPC task can be completed when FindYourEpc finds no epc and it is missing`(page: Page) { - // Skip to Find Your EPC page and submit "No EPC Found" - val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() - assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - whenever( - epcRegisterClient.getByRrn(NONEXISTENT_EPC_CERTIFICATE_NUMBER), - ).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - findYourEpcPage.submitNonexistentEpcNumber() - val epcNotFoundPage = assertPageIs(page, EpcNotFoundFormPagePropertyRegistration::class) - - // EPC not found - render page - assertThat(epcNotFoundPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(epcNotFoundPage.heading).containsText("We could not find your EPC") - assertThat(epcNotFoundPage.certificateNumberText).containsText(NONEXISTENT_EPC_CERTIFICATE_NUMBER) - assertThat(epcNotFoundPage.searchAgainLink).isVisible() - - // Click 'search again' to return to Find Your EPC and re-submit not found - epcNotFoundPage.searchAgainLink.click() - val findYourEpcPageAgain = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) - assertThat(findYourEpcPageAgain.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - whenever( - epcRegisterClient.getByRrn(NONEXISTENT_EPC_CERTIFICATE_NUMBER), - ).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - findYourEpcPageAgain.submitNonexistentEpcNumber() - assertPageIs(page, EpcNotFoundFormPagePropertyRegistration::class).form.submit() - - val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) - - // Is EPC required - render page - assertThat(isEpcRequiredPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") - isEpcRequiredPage.submitEpcRequired() - val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) - - // EPC Missing - render page - assertThat(epcMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - assertThat(epcMissingPage.continueAnywayButton).containsText("Continue anyway") - assertThat( - epcMissingPage.warning, - ).containsText("You can be fined for letting a property that does not meet energy efficiency requirements.") - epcMissingPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - checkEpcAnswersPage.form.submit() - assertPageIs(page, TaskListPagePropertyRegistration::class) - } - - @Test - fun `User can navigate the MEES flow when they have a MEES exemption`(page: Page) { - val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() - - // Has MEES Exemption - render page - assertThat(hasMeesExemptionPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(hasMeesExemptionPage.heading).containsText("You need a registered energy efficiency exemption to let this property") - hasMeesExemptionPage.submitHasMeesExemption() - val meesExemptionPage = assertPageIs(page, MeesExemptionFormPagePropertyRegistration::class) - - // MEES Exemption - select exemption reason - assertThat(meesExemptionPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - meesExemptionPage.submitExemptionReason(MeesExemptionReason.HIGH_COST) - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - } - - @Test - fun `User can navigate the MEES flow when they do not have a MEES exemption`(page: Page) { - val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() - - // Has MEES Exemption - submit no exemption - assertThat(hasMeesExemptionPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - hasMeesExemptionPage.submitHasNoMeesExemption() - val lowEnergyRatingPage = assertPageIs(page, LowEnergyRatingFormPagePropertyRegistration::class) - - // Low Energy Rating - render page - assertThat(lowEnergyRatingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) - assertThat(lowEnergyRatingPage.heading).containsText("This property does not meet energy efficiency requirements for letting") - lowEnergyRatingPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - } - - @Test - fun `User can navigate the EPC exemption flow`(page: Page) { - val epcExemptionPage = navigator.skipToPropertyRegistrationEpcExemptionPage() - - // EPC Exemption - select exemption reason - assertThat(epcExemptionPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) - epcExemptionPage.submitExemptionReason(EpcExemptionReason.PROTECTED_ARCHITECTURAL_OR_HISTORICAL_MERIT) - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - - // Check EPC Answers - render page - assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") - } - - @Test - fun `task list back link navigates to start page after entering from start page`(page: Page) { - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPage.backLink.clickAndWait() - assertPageIs(page, RegisterPropertyStartPage::class) - } - - @Test - fun `task list back link navigates to start page after entering from start page and returning from a task`(page: Page) { - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPage.clickRegisterTaskWithName("Property address") - assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - - val backLink = BackLink.default(page) - backLink.clickAndWait() - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPage.backLink.clickAndWait() - assertPageIs(page, RegisterPropertyStartPage::class) - } - - @Test - fun `restructured task list shows three sections with expected task order`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - assertEquals(3, taskListPage.getSectionCount()) - assertThat(taskListPage.getSectionHeading(0)).hasText("About your property") - assertThat(taskListPage.getSectionHeading(1)).hasText("How your property’s rented out") - assertThat(taskListPage.getSectionHeading(2)).hasText("Submit your registration") - assertEquals( - listOf("Property details", "Ownership and landlords", "Tell us if your property’s occupied"), - taskListPage.getAboutYourPropertyTaskNames(), - ) - assertEquals( - listOf( - "Tell us if your property needs a license", - "Gas safety certificate", - "Electrical safety certificate", - "Energy performance certificate (EPC)", - "Tenancy details", - ), - taskListPage.getRentedOutTaskNames(), - ) - assertEquals( - listOf("Check and submit your answers"), - taskListPage.getSubmitYourRegistrationTaskNames(), - ) - - assertTrue(taskListPage.getAboutYourPropertyTask("Property details").hasLink) - taskListPage.clickAboutYourPropertyTaskWithName("Property details") - assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - } - - @Test - fun `restructured task list shows tenancy details as not required when the property is unoccupied`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - - val taskListPage = navigator.goToRestructuredPropertyRegistrationTaskListUnoccupied() - val tenancyDetailsTask = taskListPage.getRentedOutTask("Tenancy details") - - // The label uses a non-breaking space so "Not required" doesn't wrap onto two lines when hint text is present - assertEquals("Not\u00A0required", tenancyDetailsTask.statusText.trim()) - assertEquals( - "We’ll ask for tenancy details when your property becomes occupied", - tenancyDetailsTask.hintText.trim(), - ) - assertFalse(tenancyDetailsTask.hasLink) - - val checkAndSubmitTask = taskListPage.getSubmitYourRegistrationTask("Check and submit your answers") - assertTrue(checkAndSubmitTask.hasLink) - taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - // Bedrooms is collected as a property detail for all properties, so it is shown on the CYA even when unoccupied - assertThat(checkAnswersPage.summaryList.numberOfBedroomsRow.value).containsText("3") - } - - @Test - @Suppress("ktlint:standard:max-line-length") - fun `restructured occupied journey reaches check answers after EPC and tenancy details`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPage.clickAboutYourPropertyTaskWithName("Property details") - val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") - val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) - selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") - val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) - propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) - val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) - bedroomsPage.submitNumOfBedrooms(3) - val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) - ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) - - val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - hasJointLandlordsPage.submitHasNoJointLandlords() - - val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") - occupancyPage.submitIsOccupied() - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") - licensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) - val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") - hasGasSupplyPage.submitHasNoGasSupply() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - assertThat(checkGasSafetyAnswersPage.sectionHeader).isHidden() - checkGasSafetyAnswersPage.form.submit() - - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPage.clickRentedOutTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - hasElectricalCertPage.submitProvideThisLater() - val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) - provideElectricalCertLaterPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - assertThat(checkElectricalSafetyAnswersPage.sectionHeader).isHidden() - - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - checkElectricalSafetyAnswersPage.form.submit() - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPage.clickRentedOutTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - hasEpcPage.submitProvideThisLater() - val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) - provideEpcLaterPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - assertThat(checkEpcAnswersPage.sectionHeader).isHidden() - checkEpcAnswersPage.form.submit() - - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - assertTrue(taskListPage.getRentedOutTask("Tenancy details").hasLink) - taskListPage.clickRentedOutTaskWithName("Tenancy details") - val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) - householdsPage.submitNumberOfHouseholds(2) - val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) - peoplePage.submitNumOfPeople(2) - val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) - rentIncludesBillsPage.submitIsNotIncluded() - val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) - furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) - val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) - rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) - rentAmountPage.submitRentAmount("400") - - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - } - - @Test - fun `restructured occupied journey supports provide licensing later and shows it on check answers`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - taskListPage.clickAboutYourPropertyTaskWithName("Property details") - val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") - val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) - selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") - val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) - propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) - val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) - bedroomsPage.submitNumOfBedrooms(3) - val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) - ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) - - val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - hasJointLandlordsPage.submitHasNoJointLandlords() - - val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - occupancyPage.submitIsOccupied() - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - licensingTypePage.submitProvideThisLater() - val provideLicensingLaterPage = assertPageIs(page, ProvideLicensingLaterFormPagePropertyRegistration::class) - assertThat(provideLicensingLaterPage.insetText).isVisible() - provideLicensingLaterPage.form.submit() - - val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - hasGasSupplyPage.submitHasNoGasSupply() - val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - checkGasSafetyAnswersPage.form.submit() - - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPage.clickRentedOutTaskWithName("Electrical safety certificate") - val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - hasElectricalCertPage.submitProvideThisLater() - val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) - provideElectricalCertLaterPage.form.submit() - val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) - whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - checkElectricalSafetyAnswersPage.form.submit() - - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPage.clickRentedOutTaskWithName("Energy performance certificate (EPC)") - val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) - hasEpcPage.submitProvideThisLater() - val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) - provideEpcLaterPage.form.submit() - val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) - checkEpcAnswersPage.form.submit() - - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPage.clickRentedOutTaskWithName("Tenancy details") - val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) - householdsPage.submitNumberOfHouseholds(2) - val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) - peoplePage.submitNumOfPeople(2) - val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) - rentIncludesBillsPage.submitIsNotIncluded() - val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) - furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) - val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) - rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) - rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) - rentAmountPage.submitRentAmount("400") - - taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") - val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - assertThat(checkAnswersPage.summaryList.licensingRow.value).containsText("Provide this later") - } - - @Test - fun `restructured task list shows grouping tasks as cannot start yet until unlocked on a new journey`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - - val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() - registerPropertyStartPage.startButton.clickAndWait() - val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) - - val propertyDetailsTask = taskListPage.getAboutYourPropertyTask("Property details") - assertEquals("Not started", propertyDetailsTask.statusText.trim()) - assertTrue(propertyDetailsTask.hasLink) - - val ownershipTask = taskListPage.getAboutYourPropertyTask("Ownership and landlords") - assertEquals("Cannot start yet", ownershipTask.statusText.trim()) - assertFalse(ownershipTask.hasLink) - - assertEquals("Cannot start yet", taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Tell us if your property needs a license").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Gas safety certificate").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Tenancy details").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getSubmitYourRegistrationTask("Check and submit your answers").statusText.trim()) - } - - @Test - fun `restructured task list shows a grouping task as in progress when it is partially completed`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - - // The address and property type have been answered, but not the number of bedrooms, so the "Property details" - // grouping task (which now contains all three) is partway through. - val taskListPage = - navigator.goToRestructuredPropertyRegistrationTaskList(PropertyStateSessionBuilder.beforePropertyRegistrationOwnershipType()) - - assertEquals("In progress", taskListPage.getAboutYourPropertyTask("Property details").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getAboutYourPropertyTask("Ownership and landlords").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Gas safety certificate").statusText.trim()) - assertEquals("Cannot start yet", taskListPage.getSubmitYourRegistrationTask("Check and submit your answers").statusText.trim()) - } + findYourEpcPage.submitSupersededEpcNumber() + val epcSupersededPage = assertPageIs(page, EpcSuperseededFormPagePropertyRegistration::class) + + // Check details of superseded and latest epc - render page + assertThat(epcSupersededPage.sectionHeader).containsText(epcSectionHeader) + epcSupersededPage.submitContinueWithLatest() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + assertPageIs(page, TaskListPagePropertyRegistration::class) + } + + @Test + fun `The EPC task can be completed when FindYourEpc finds no epc and it is missing`(page: Page) { + // Skip to Find Your EPC page and submit "No EPC Found" + val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() + assertThat(findYourEpcPage.form.sectionHeader).containsText(epcSectionHeader) + whenever( + epcRegisterClient.getByRrn(NONEXISTENT_EPC_CERTIFICATE_NUMBER), + ).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + findYourEpcPage.submitNonexistentEpcNumber() + val epcNotFoundPage = assertPageIs(page, EpcNotFoundFormPagePropertyRegistration::class) + + // EPC not found - render page + assertThat(epcNotFoundPage.sectionHeader).containsText(epcSectionHeader) + assertThat(epcNotFoundPage.heading).containsText("We could not find your EPC") + assertThat(epcNotFoundPage.certificateNumberText).containsText(NONEXISTENT_EPC_CERTIFICATE_NUMBER) + assertThat(epcNotFoundPage.searchAgainLink).isVisible() + + // Click 'search again' to return to Find Your EPC and re-submit not found + epcNotFoundPage.searchAgainLink.click() + val findYourEpcPageAgain = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) + assertThat(findYourEpcPageAgain.form.sectionHeader).containsText(epcSectionHeader) + whenever( + epcRegisterClient.getByRrn(NONEXISTENT_EPC_CERTIFICATE_NUMBER), + ).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + findYourEpcPageAgain.submitNonexistentEpcNumber() + assertPageIs(page, EpcNotFoundFormPagePropertyRegistration::class).form.submit() + + val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) + + // Is EPC required - render page + assertThat(isEpcRequiredPage.form.sectionHeader).containsText(epcSectionHeader) + assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") + isEpcRequiredPage.submitEpcRequired() + val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) + + // EPC Missing - render page + assertThat(epcMissingPage.sectionHeader).containsText(epcSectionHeader) + assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + assertThat(epcMissingPage.continueAnywayButton).containsText("Continue anyway") + assertThat( + epcMissingPage.warning, + ).containsText("You can be fined for letting a property that does not meet energy efficiency requirements.") + epcMissingPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + assertPageIs(page, TaskListPagePropertyRegistration::class) + } + + @Test + fun `User can navigate the MEES flow when they have a MEES exemption`(page: Page) { + val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() + + // Has MEES Exemption - render page + assertThat(hasMeesExemptionPage.sectionHeader).containsText(epcSectionHeader) + assertThat(hasMeesExemptionPage.heading).containsText("You need a registered energy efficiency exemption to let this property") + hasMeesExemptionPage.submitHasMeesExemption() + val meesExemptionPage = assertPageIs(page, MeesExemptionFormPagePropertyRegistration::class) + + // MEES Exemption - select exemption reason + assertThat(meesExemptionPage.form.sectionHeader).containsText(epcSectionHeader) + meesExemptionPage.submitExemptionReason(MeesExemptionReason.HIGH_COST) + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + } + + @Test + fun `User can navigate the MEES flow when they do not have a MEES exemption`(page: Page) { + val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() + + // Has MEES Exemption - submit no exemption + assertThat(hasMeesExemptionPage.sectionHeader).containsText(epcSectionHeader) + hasMeesExemptionPage.submitHasNoMeesExemption() + val lowEnergyRatingPage = assertPageIs(page, LowEnergyRatingFormPagePropertyRegistration::class) + + // Low Energy Rating - render page + assertThat(lowEnergyRatingPage.sectionHeader).containsText(epcSectionHeader) + assertThat(lowEnergyRatingPage.heading).containsText("This property does not meet energy efficiency requirements for letting") + lowEnergyRatingPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + } + + @Test + fun `User can navigate the EPC exemption flow`(page: Page) { + val epcExemptionPage = navigator.skipToPropertyRegistrationEpcExemptionPage() + + // EPC Exemption - select exemption reason + assertThat(epcExemptionPage.form.sectionHeader).containsText(epcSectionHeader) + epcExemptionPage.submitExemptionReason(EpcExemptionReason.PROTECTED_ARCHITECTURAL_OR_HISTORICAL_MERIT) + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + } + + @Test + fun `task list back link navigates to start page after entering from start page`(page: Page) { + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.backLink.clickAndWait() + assertPageIs(page, RegisterPropertyStartPage::class) + } + + @Test + fun `task list back link navigates to start page after entering from start page and returning from a task`(page: Page) { + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.clickRegisterTaskWithName("Property details") + assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + + val backLink = BackLink.default(page) + backLink.clickAndWait() + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.backLink.clickAndWait() + assertPageIs(page, RegisterPropertyStartPage::class) + } + + @Test + fun `restructured task list shows three sections with expected task order`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + assertEquals(3, taskListPage.getSectionCount()) + assertThat(taskListPage.getSectionHeading(0)).hasText("About your property") + assertThat(taskListPage.getSectionHeading(1)).hasText("How your property’s rented out") + assertThat(taskListPage.getSectionHeading(2)).hasText("Submit your registration") + assertEquals( + listOf("Property details", "Ownership and landlords", "Tell us if your property’s occupied"), + taskListPage.getAboutYourPropertyTaskNames(), + ) + assertEquals( + listOf( + "Tell us if your property needs a license", + "Gas safety certificate", + "Electrical safety certificate", + "Energy performance certificate (EPC)", + "Tenancy details", + ), + taskListPage.getRentedOutTaskNames(), + ) + assertEquals( + listOf("Check and submit your answers"), + taskListPage.getSubmitYourRegistrationTaskNames(), + ) - @Test - fun `restructured task list shows grouping tasks as complete when their answers are provided`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + assertTrue(taskListPage.getAboutYourPropertyTask("Property details").hasLink) + taskListPage.clickAboutYourPropertyTaskWithName("Property details") + assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + } - navigator.skipToPropertyRegistrationCheckAnswersPageOccupied() - val taskListPage = navigator.goToPropertyRegistrationTaskList() + @Test + fun `restructured task list shows tenancy details as not required when the property is unoccupied`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - assertEquals("Completed", taskListPage.getAboutYourPropertyTask("Property details").statusText.trim()) - assertEquals("Completed", taskListPage.getAboutYourPropertyTask("Ownership and landlords").statusText.trim()) - assertEquals("Completed", taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.trim()) - assertEquals("Completed", taskListPage.getRentedOutTask("Tenancy details").statusText.trim()) + val taskListPage = navigator.goToRestructuredPropertyRegistrationTaskListUnoccupied() + val tenancyDetailsTask = taskListPage.getRentedOutTask("Tenancy details") - val checkAndSubmitTask = taskListPage.getSubmitYourRegistrationTask("Check and submit your answers") - assertEquals("Not started", checkAndSubmitTask.statusText.trim()) - assertTrue(checkAndSubmitTask.hasLink) + // The label uses a non-breaking space so "Not required" doesn't wrap onto two lines when hint text is present + assertEquals("Not\u00A0required", tenancyDetailsTask.statusText.trim()) + assertEquals( + "We’ll ask for tenancy details when your property becomes occupied", + tenancyDetailsTask.hintText.trim(), + ) + assertFalse(tenancyDetailsTask.hasLink) + + val checkAndSubmitTask = taskListPage.getSubmitYourRegistrationTask("Check and submit your answers") + assertTrue(checkAndSubmitTask.hasLink) + taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + // Bedrooms is collected as a property detail for all properties, so it is shown on the CYA even when unoccupied + assertThat(checkAnswersPage.summaryList.numberOfBedroomsRow.value).containsText("3") + } + + @Test + @Suppress("ktlint:standard:max-line-length") + fun `restructured occupied journey reaches check answers after EPC and tenancy details`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.clickAboutYourPropertyTaskWithName("Property details") + val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") + val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) + selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") + val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) + propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) + val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) + bedroomsPage.submitNumOfBedrooms(3) + val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) + + val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + hasJointLandlordsPage.submitHasNoJointLandlords() + + val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") + occupancyPage.submitIsOccupied() + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") + licensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") + hasGasSupplyPage.submitHasNoGasSupply() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + assertThat(checkGasSafetyAnswersPage.sectionHeader).isHidden() + checkGasSafetyAnswersPage.form.submit() + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickRentedOutTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + hasElectricalCertPage.submitProvideThisLater() + val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) + provideElectricalCertLaterPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + assertThat(checkElectricalSafetyAnswersPage.sectionHeader).isHidden() + + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + checkElectricalSafetyAnswersPage.form.submit() + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickRentedOutTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + hasEpcPage.submitProvideThisLater() + val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) + provideEpcLaterPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + assertThat(checkEpcAnswersPage.sectionHeader).isHidden() + checkEpcAnswersPage.form.submit() + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + assertTrue(taskListPage.getRentedOutTask("Tenancy details").hasLink) + taskListPage.clickRentedOutTaskWithName("Tenancy details") + val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) + householdsPage.submitNumberOfHouseholds(2) + val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) + peoplePage.submitNumOfPeople(2) + val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) + rentIncludesBillsPage.submitIsNotIncluded() + val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) + furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) + val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) + rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) + rentAmountPage.submitRentAmount("400") + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + } + + @Test + fun `restructured task list shows grouping tasks as cannot start yet until unlocked on a new journey`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + val propertyDetailsTask = taskListPage.getAboutYourPropertyTask("Property details") + assertEquals("Not started", propertyDetailsTask.statusText.trim()) + assertTrue(propertyDetailsTask.hasLink) + + val ownershipTask = taskListPage.getAboutYourPropertyTask("Ownership and landlords") + assertEquals("Cannot start yet", ownershipTask.statusText.trim()) + assertFalse(ownershipTask.hasLink) + + assertEquals("Cannot start yet", taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Tell us if your property needs a license").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Gas safety certificate").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Tenancy details").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getSubmitYourRegistrationTask("Check and submit your answers").statusText.trim()) + } + + @Test + fun `restructured task list shows a grouping task as in progress when it is partially completed`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + // The address and property type have been answered, but not the number of bedrooms, so the "Property details" + // grouping task (which now contains all three) is partway through. + val taskListPage = + navigator.goToRestructuredPropertyRegistrationTaskList( + PropertyStateSessionBuilder.beforePropertyRegistrationOwnershipType(), + ) + + assertEquals("In progress", taskListPage.getAboutYourPropertyTask("Property details").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getAboutYourPropertyTask("Ownership and landlords").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getRentedOutTask("Gas safety certificate").statusText.trim()) + assertEquals("Cannot start yet", taskListPage.getSubmitYourRegistrationTask("Check and submit your answers").statusText.trim()) + } + + @Test + fun `restructured task list shows grouping tasks as complete when their answers are provided`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + navigator.skipToPropertyRegistrationCheckAnswersPageOccupied() + val taskListPage = navigator.goToPropertyRegistrationTaskList() + + assertEquals("Completed", taskListPage.getAboutYourPropertyTask("Property details").statusText.trim()) + assertEquals("Completed", taskListPage.getAboutYourPropertyTask("Ownership and landlords").statusText.trim()) + assertEquals("Completed", taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.trim()) + assertEquals("Completed", taskListPage.getRentedOutTask("Tenancy details").statusText.trim()) + + val checkAndSubmitTask = taskListPage.getSubmitYourRegistrationTask("Check and submit your answers") + assertEquals("Not started", checkAndSubmitTask.statusText.trim()) + assertTrue(checkAndSubmitTask.hasLink) + } + + @Test + fun `restructured occupied journey supports provide licensing later and shows it on check answers`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.clickAboutYourPropertyTaskWithName("Property details") + val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") + val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) + selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") + val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) + propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) + val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) + bedroomsPage.submitNumOfBedrooms(3) + val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) + + val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + hasJointLandlordsPage.submitHasNoJointLandlords() + + val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + occupancyPage.submitIsOccupied() + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + licensingTypePage.submitProvideThisLater() + val provideLicensingLaterPage = assertPageIs(page, ProvideLicensingLaterFormPagePropertyRegistration::class) + assertThat(provideLicensingLaterPage.insetText).isVisible() + provideLicensingLaterPage.form.submit() + + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + hasGasSupplyPage.submitHasNoGasSupply() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + checkGasSafetyAnswersPage.form.submit() + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickRentedOutTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + hasElectricalCertPage.submitProvideThisLater() + val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) + provideElectricalCertLaterPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + checkElectricalSafetyAnswersPage.form.submit() + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickRentedOutTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + hasEpcPage.submitProvideThisLater() + val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) + provideEpcLaterPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + checkEpcAnswersPage.form.submit() + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickRentedOutTaskWithName("Tenancy details") + val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) + householdsPage.submitNumberOfHouseholds(2) + val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) + peoplePage.submitNumOfPeople(2) + val bedroomsPage2 = assertPageIs(page, OccupancyNumberOfBedroomsFormPagePropertyRegistration::class) + bedroomsPage2.submitNumOfBedrooms(3) + val rentIncludesBillsPage = assertPageIs(page, OccupancyRentIncludesBillsFormPagePropertyRegistration::class) + rentIncludesBillsPage.submitIsNotIncluded() + val furnishedPage = assertPageIs(page, OccupancyFurnishedStatusFormPagePropertyRegistration::class) + furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) + val rentFrequencyPage = assertPageIs(page, OccupancyRentFrequencyFormPagePropertyRegistration::class) + rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, OccupancyRentAmountFormPagePropertyRegistration::class) + rentAmountPage.submitRentAmount("400") + + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + assertThat(checkAnswersPage.summaryList.licensingTypeRow.value).containsText("Provide this later") + } + + @Test + fun `numeric values with leading zeros are displayed without leading zeros on the CYA page`(page: Page) { + val checkAnswersPage = + navigator.skipToPropertyRegistrationCheckAnswersPageOccupied( + households = 2, + people = 4, + bedrooms = 3, + rentAmount = "0000000.1", + ) + + assertThat(checkAnswersPage.summaryList.rentAmountRow.value).containsText("£0.1") + assertThat(checkAnswersPage.summaryList.numberOfHouseholdsRow.value).containsText("2") + assertThat(checkAnswersPage.summaryList.numberOfTenantsRow.value).containsText("4") + assertThat(checkAnswersPage.summaryList.numberOfBedroomsRow.value).containsText("3") + } + + @Test + fun `CYA joint landlords row shows a change link to the check joint landlords page when landlords are invited`(page: Page) { + val taskListPage = + navigator.goToRestructuredPropertyRegistrationTaskList( + PropertyStateSessionBuilder + .beforePropertyRegistrationCheckAnswersOccupied() + .withCheckedJointLandlords(mutableListOf("email@address.com")), + ) + taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + val changeLink = + checkAnswersPage.summaryList.jointLandlordsInvitationsRow.actions + .getActionLink("Change") + assertThat(changeLink).isVisible() + + changeLink.clickAndWait() + val checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordsPage.summaryList.firstRow.value).containsText("email@address.com") + } + + @Test + fun `CYA joint landlords row shows a change link to the has joint landlords page when there are no joint landlords`(page: Page) { + val taskListPage = + navigator.goToRestructuredPropertyRegistrationTaskList( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckAnswersOccupied(), + ) + taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + val changeLink = + checkAnswersPage.summaryList.jointLandlordsAreThereRow.actions + .getActionLink("Change") + assertThat(changeLink).isVisible() + + changeLink.clickAndWait() + assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + } + + @Test + fun `a landlord cannot invite themselves as a joint landlord`(page: Page) { + val inviteJointLandlordPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + + inviteJointLandlordPage.submitEmail("alex.surname@example.com") + + val inviteJointLandlordPageWithError = assertPageIs(page, InviteJointLandlordFormPagePropertyRegistration::class) + assertThat(inviteJointLandlordPageWithError.form.getErrorMessage()) + .containsText("You cannot invite yourself as a joint landlord") + + inviteJointLandlordPageWithError.submitEmail("someone.else@example.com") + assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + } } companion object { @@ -1723,60 +1798,1360 @@ class PropertyRegistrationJourneyTests : IntegrationTestWithMutableData("data-lo val uprnForSelectedAddress = 1L // This matches the uprn in data-local.sql for address 1 Fictional Road, FA1 1AA } - @Test - fun `numeric values with leading zeros are displayed without leading zeros on the CYA page`(page: Page) { - val checkAnswersPage = - navigator.skipToPropertyRegistrationCheckAnswersPageOccupied( - households = 2, - people = 4, - bedrooms = 3, - rentAmount = "0000000.1", + // TODO PDJB-1340: Remove tests when the PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING Feature Flag is removed + @Nested + inner class RestructureAndSkippingDisabled { + private val propertyRegistrationSectionHeader = "Section 1 of 2 — Add property details" + + @BeforeEach + fun disableRestructureAndSkippingFlag() { + featureFlagManager.disableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + } + + @Test + @Suppress("ktlint:standard:max-line-length") + fun `User can navigate the whole journey if pages are correctly filled in (select address, non-custom property type, selective license, occupied, compliance certificates uploaded)`( + page: Page, + ) { + // Start page (not a journey step, but it is how the user accesses the journey) + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + assertThat(registerPropertyStartPage.heading).containsText("Register a property") + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // Task list page (part of the journey to support redirects) + taskListPage.clickRegisterTaskWithName("Property address") + val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + + // Address lookup - render page + assertThat(addressLookupPage.form.fieldsetHeading).containsText("What is the property address?") + assertThat(addressLookupPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AA", "1") + val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) + + // Select address - render page + assertThat(selectAddressPage.form.fieldsetHeading).containsText("Select your address") + assertThat(selectAddressPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + selectAddressPage.selectAddressAndSubmit("1 Fictional Road, FA1 1AA") + val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) + + // Verify incomplete property is created at this point + verify(landlordIncompletePropertiesRepository).save(any()) + + // Property type selection - render page + assertThat(propertyTypePage.form.fieldsetHeading).containsText("What type of property are you registering?") + assertThat(propertyTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + propertyTypePage.submitPropertyType(PropertyType.DETACHED_HOUSE) + val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + + // Ownership type selection - render page + assertThat(ownershipTypePage.form.fieldsetHeading).containsText("Select the type of ownership you have for your property") + assertThat(ownershipTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + + // Licensing type - render page + assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") + assertThat(licensingTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + licensingTypePage.submitLicensingType(LicensingType.SELECTIVE_LICENCE) + val selectiveLicencePage = assertPageIs(page, SelectiveLicenceFormPagePropertyRegistration::class) + + // Selective licence - render page + assertThat(selectiveLicencePage.form.fieldsetHeading).containsText("What is your selective licence number?") + assertThat(selectiveLicencePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + selectiveLicencePage.submitLicenseNumber("licence number") + val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + + // Occupancy - render page + assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") + assertThat(occupancyPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + occupancyPage.submitIsOccupied() + val householdsPage = assertPageIs(page, NumberOfHouseholdsFormPagePropertyRegistration::class) + + // Number of households - render page + assertThat(householdsPage.header).containsText("Households in your property") + assertThat(householdsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + householdsPage.submitNumberOfHouseholds(2) + val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) + + // Number of people - render page + assertThat(peoplePage.header).containsText("How many people live in your property?") + assertThat(peoplePage.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + peoplePage.submitNumOfPeople(2) + val bedroomsPage = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) + + // Number of bedrooms - render page + assertThat(bedroomsPage.header).containsText("How many bedrooms in your property?") + assertThat(bedroomsPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + bedroomsPage.submitNumOfBedrooms(3) + val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) + + // Does the rent include bills - render page + assertThat(rentIncludesBillsPage.form.fieldsetHeading).containsText("Does the rent include bills?") + assertThat(rentIncludesBillsPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + rentIncludesBillsPage.submitIsIncluded() + val billsIncludedPage = assertPageIs(page, BillsIncludedFormPagePropertyRegistration::class) + + // Bills included - render page + assertThat(billsIncludedPage.form.fieldsetHeading).containsText("Which of these do you include in the rent?") + assertThat(billsIncludedPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.selectSomethingElseCheckbox() + billsIncludedPage.fillCustomBills("Dog Grooming") + billsIncludedPage.form.submit() + val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) + + // Furnished - render page + assertThat(furnishedPage.form.fieldsetHeading).containsText("Is the property furnished?") + assertThat(furnishedPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) + val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) + + // Rent frequency - render page + assertThat(rentFrequencyPage.header).containsText("When you charge rent") + assertThat(rentFrequencyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + rentFrequencyPage.selectRentFrequency(RentFrequency.OTHER) + rentFrequencyPage.fillCustomRentFrequency("Fortnightly") + rentFrequencyPage.form.submit() + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) + + // Rent amount - render page + assertThat(rentAmountPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + rentAmountPage.submitRentAmount("400") + val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + + // Has Joint Landlords - render page + assertThat(hasJointLandlordsPage.header).containsText("Invite joint landlords") + assertThat(hasJointLandlordsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + + // fill in and submit + hasJointLandlordsPage.submitHasJointLandlords() + val inviteJointLandlordPage = assertPageIs(page, InviteJointLandlordFormPagePropertyRegistration::class) + + // Invite joint landlord - render page + assertThat(inviteJointLandlordPage.heading).containsText("Invite a joint landlord to this property") + assertThat(inviteJointLandlordPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + + // fill in and submit + inviteJointLandlordPage.submitEmail("email@address.com") + var checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(checkJointLandlordsPage.summaryList.firstRow.value).containsText("email@address.com") + + // Check joint landlords - render page + checkJointLandlordsPage + .form + .addAnotherButton + .clickAndWait() + + // Invite another joint landlord - render page + val addAnotherPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + assertThat(addAnotherPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + addAnotherPage.submitEmail("email2@address.com") + + checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordsPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + + // Remove Joint Landlord - render page + val removeJointLandlordsPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordsPage.submitWantsToProceed() + + checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordsPage.form.submit() + + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + + // Has Gas Supply - render page + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert - render page + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasGasCertPage.heading).containsText("Do you have a gas safety certificate for this property?") + hasGasCertPage.submitHasCertificate() + val gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page + assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") + gasCertIssueDatePage.submitDate(validGasSafetyCertIssueDate) + var uploadGasCertPage = assertPageIs(page, UploadGasCertFormPagePropertyRegistration::class) + + // Upload Gas Cert - render page + assertThat(uploadGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + uploadGasCertPage.uploadGasCertificate(Path.of("src/test/resources/test-files/blank.png")) + var checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) + + // Check Gas Cert Uploads - render page + assertThat(checkGasCertUploadsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(checkGasCertUploadsPage.heading).containsText("You’ve uploaded 1 file") + assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + assertEquals(checkGasCertUploadsPage.table.rows.count(), 1) + checkGasCertUploadsPage.form.addAnotherButton.clickAndWait() + uploadGasCertPage = assertPageIs(page, UploadGasCertFormPagePropertyRegistration::class) + + uploadGasCertPage.uploadGasCertificate(Path.of("src/test/resources/test-files/blank.png")) + checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) + + assertThat(checkGasCertUploadsPage.heading).containsText("You’ve uploaded 2 files") + assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + assertThat(checkGasCertUploadsPage.table.getCell(1, 0)).containsText("blank.png") + assertEquals(checkGasCertUploadsPage.table.rows.count(), 2) + + checkGasCertUploadsPage.table + .getClickableCell(0, 2) + .link + .clickAndWait() + + val removeGasCertUploadPage = assertPageIs(page, RemoveGasCertUploadFormPagePropertyRegistration::class) + + removeGasCertUploadPage.form.radios.selectValue("true") + removeGasCertUploadPage.form.submit() + + checkGasCertUploadsPage = assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) + assertThat(checkGasCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + + assertEquals(checkGasCertUploadsPage.table.rows.count(), 1) + checkGasCertUploadsPage.form.submit() + + // Remove Gas Cert Upload - render page + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasEic() + val electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date - render page + assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat( + electricalCertExpiryDatePage.heading, + ).containsText("What’s the expiry date on the Electrical Installation Certificate?") + electricalCertExpiryDatePage.submitDate(validExpiryDate) + var uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) + + // Upload Electrical Cert - render page + assertThat(uploadElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) + var checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + + // Check Electrical Cert Uploads - render page + assertThat(checkElectricalCertUploadsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 1) + checkElectricalCertUploadsPage.form.addAnotherButton.clickAndWait() + uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) + + uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) + checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + assertThat(checkElectricalCertUploadsPage.table.getCell(1, 0)).containsText("blank.png") + assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 2) + + checkElectricalCertUploadsPage.table + .getClickableCell(0, 2) + .link + .clickAndWait() + + val removeElectricalCertUploadPage = assertPageIs(page, RemoveElectricalCertUploadFormPagePropertyRegistration::class) + + removeElectricalCertUploadPage.form.radios.selectValue("true") + removeElectricalCertUploadPage.form.submit() + + checkElectricalCertUploadsPage = assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + assertThat(checkElectricalCertUploadsPage.table.getCell(0, 0)).containsText("blank.png") + + assertEquals(checkElectricalCertUploadsPage.table.rows.count(), 1) + checkElectricalCertUploadsPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep being able to find an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)) + .thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + expiryDate = validExpiryDate, + ), + ) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // EpcLookupByUprnStep finds the EPC, so redirects to Check UPRN matched EPC + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val confirmUprnMatchedEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) + + // Confirm UPRN matched EPC - submit No (don't use this EPC) + assertThat(confirmUprnMatchedEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + confirmUprnMatchedEpcDetailsPage.submitNo() + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasEpcPage.submitHasEpc() + val findYourEpcPage = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) + + // EPC Search - render page + assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + whenever(epcRegisterClient.getByRrn(CURRENT_EPC_CERTIFICATE_NUMBER)) + .thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + certificateNumber = CURRENT_EPC_CERTIFICATE_NUMBER, + latestCertificateNumberForThisProperty = CURRENT_EPC_CERTIFICATE_NUMBER, + expiryDate = validExpiryDate, + ), + ) + findYourEpcPage.submitCurrentEpcNumber() + val confirmEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByCertificateNumberPagePropertyRegistration::class) + + // Check Matched EPC - render page + assertThat(confirmEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + val expectedExpiryDate = + validExpiryDate + .toJavaLocalDate() + .format(DateTimeFormatter.ofPattern("d MMMM yyyy")) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.addressRow.value).containsText(MockEpcData.defaultSingleLineAddress) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.energyEfficiencyRatingRow.value).containsText("C") + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.expiryDateRow.value).containsText(expectedExpiryDate) + assertThat( + confirmEpcDetailsPage.summaryCard.summaryList.certificateNumberRow.value, + ).containsText(CURRENT_EPC_CERTIFICATE_NUMBER) + confirmEpcDetailsPage.submitYes() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + // Check answers - render page + assertThat(checkAnswersPage.heading).containsText("Check your answers for:") + assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") + assertThat(checkAnswersPage.complianceCertificatesHeading).isVisible() + assertThat(checkAnswersPage.gasSafetyHeading).isVisible() + assertThat(checkAnswersPage.electricalSafetyHeading).isVisible() + assertThat(checkAnswersPage.epcHeading).isVisible() + // submit + checkAnswersPage.confirm() + val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) + + // Confirmation - render page + val propertyOwnershipCaptor = captor() + verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) + val expectedPropertyRegNum = + RegistrationNumberDataModel.fromRegistrationNumber( + propertyOwnershipCaptor.value.registrationNumber, + ) + assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) + assertTrue(propertyOwnershipCaptor.value.isOccupied) + assertFalse(confirmationPage.whatYouNeedToDoNextHeading.isVisible) + assertTrue(confirmationPage.surveyLink.locator.isVisible) + assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) + + // Check confirmation email + verify(confirmationEmailSender).sendEmail( + "alex.surname@example.com", + PropertyRegistrationConfirmationEmail( + expectedPropertyRegNum.toString(), + "1 Fictional Road, FA1 1AA", + absoluteLandlordUrl, + true, + listOf("email2@address.com"), + ), ) - assertThat(checkAnswersPage.summaryList.rentAmountRow.value).containsText("£0.1") - assertThat(checkAnswersPage.summaryList.numberOfHouseholdsRow.value).containsText("2") - assertThat(checkAnswersPage.summaryList.numberOfTenantsRow.value).containsText("4") - assertThat(checkAnswersPage.summaryList.numberOfBedroomsRow.value).containsText("3") - } - - @Test - fun `CYA joint landlords row shows a change link to the check joint landlords page when landlords are invited`(page: Page) { - val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPageWithJointLandlords() - - val changeLink = - checkAnswersPage.summaryList.jointLandlordsInvitationsRow.actions - .getActionLink("Change") - assertThat(changeLink).isVisible() - - changeLink.clickAndWait() - val checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordsPage.summaryList.firstRow.value).containsText("email@address.com") - } - - @Test - fun `CYA joint landlords row shows a change link to the has joint landlords page when there are no joint landlords`(page: Page) { - val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() - - val changeLink = - checkAnswersPage.summaryList.jointLandlordsAreThereRow.actions - .getActionLink("Change") - assertThat(changeLink).isVisible() - - changeLink.clickAndWait() - assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - } - - @Test - fun `a landlord cannot invite themselves as a joint landlord`(page: Page) { - val inviteJointLandlordPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - - inviteJointLandlordPage.submitEmail("alex.surname@example.com") - - val inviteJointLandlordPageWithError = assertPageIs(page, InviteJointLandlordFormPagePropertyRegistration::class) - assertThat(inviteJointLandlordPageWithError.form.getErrorMessage()) - .containsText("You cannot invite yourself as a joint landlord") + // Go to dashboard + confirmationPage.goToDashboardLink.clickAndWait() + assertPageIs(page, LandlordDashboardPage::class) + } + + @Test + @Suppress("ktlint:standard:max-line-length") + fun `User can navigate the whole journey if pages are correctly filled in (manual address, custom property type, no license, unoccupied, no joint landlords, no certificates)`( + page: Page, + ) { + // Start page (not a journey step, but it is how the user accesses the journey) + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + assertThat(registerPropertyStartPage.heading).containsText("Register a property") + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // Task list page (part of the journey to support redirects) + taskListPage.clickRegisterTaskWithName("Property address") + val addressLookupPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + + // Address lookup - render page + assertThat(addressLookupPage.form.fieldsetHeading).containsText("What is the property address?") + assertThat(addressLookupPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + addressLookupPage.submitPostcodeAndBuildingNameOrNumber("FA1 1AB", "2") + val selectAddressPage = assertPageIs(page, SelectAddressFormPagePropertyRegistration::class) + + // Select address - render page + assertThat(selectAddressPage.form.fieldsetHeading).containsText("Select your address") + assertThat(selectAddressPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + selectAddressPage.selectAddressAndSubmit(MANUAL_ADDRESS_CHOSEN) + val manualAddressPage = assertPageIs(page, ManualAddressFormPagePropertyRegistration::class) + + // Manual address - render page + assertThat(manualAddressPage.form.fieldsetHeading).containsText("What is the property address?") + assertThat(manualAddressPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + manualAddressPage.submitAddress(addressLineOne = "Test address line 1", townOrCity = "Testville", postcode = "EG1 2AB") + val selectLocalCouncilPage = assertPageIs(page, SelectLocalCouncilFormPagePropertyRegistration::class) + + // Select local council - render page + assertThat(selectLocalCouncilPage.form.fieldsetHeading).containsText("What local council area is your property in?") + assertThat(selectLocalCouncilPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + selectLocalCouncilPage.submitLocalCouncil("BATH AND NORTH EAST SOMERSET COUNCIL", "BATH AND NORTH EAST SOMERSET COUNCIL") + val propertyTypePage = assertPageIs(page, PropertyTypeFormPagePropertyRegistration::class) + + // Property type selection - render page + assertThat(propertyTypePage.form.fieldsetHeading).containsText("What type of property are you registering?") + assertThat(propertyTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + propertyTypePage.submitCustomPropertyType("End terrace house") + val ownershipTypePage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + + // Ownership type selection - render page + assertThat(ownershipTypePage.form.fieldsetHeading).containsText("Select the type of ownership you have for your property") + assertThat(ownershipTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + ownershipTypePage.submitOwnershipType(OwnershipType.FREEHOLD) + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + + // Licensing type - render page + assertThat(licensingTypePage.form.fieldsetHeading).containsText("Select the type of licence you have for your property") + assertThat(licensingTypePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + licensingTypePage.submitLicensingType(LicensingType.NO_LICENSING) + val occupancyPage = assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + + // Occupancy - render page + assertThat(occupancyPage.form.fieldsetHeading).containsText("Is your property occupied by tenants?") + assertThat(occupancyPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + // fill in and submit + occupancyPage.submitIsVacant() + val hasJointLandlordsPage = assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + + // Has Joint Landlords - render page + assertThat(hasJointLandlordsPage.header).containsText("Invite joint landlords") + assertThat(hasJointLandlordsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + + // fill in and submit + hasJointLandlordsPage.submitHasNoJointLandlords() + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + + // Has Gas Supply - render page + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasGasSupplyPage.heading).containsText("Does the property have a gas supply or any gas appliances?") + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert - render page + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasGasCertPage.heading).containsText("Do you have a gas safety certificate for this property?") + hasGasCertPage.submitHasNoCertificate() + val gasCertMissingPage = assertPageIs(page, GasCertMissingFormPagePropertyRegistration::class) + + // Gas Cert Missing - render page + assertThat(gasCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertMissingPage.heading).containsText("You must get a gas safety certificate before a tenant moves in") + assertThat(gasCertMissingPage.warning).isHidden() + assertThat(gasCertMissingPage.submitButton).containsText("Continue") + gasCertMissingPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasNoCert() + val electricalCertMissingPage = assertPageIs(page, ElectricalCertMissingFormPagePropertyRegistration::class) + + // Electrical Cert Missing - render page + assertThat(electricalCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat( + electricalCertMissingPage.heading, + ).containsText("You must get an electrical safety certificate before a tenant moves in") + assertThat(electricalCertMissingPage.warning).isHidden() + assertThat(electricalCertMissingPage.submitButton).containsText("Continue") + electricalCertMissingPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // We use a manual address, uprn will be null. + // The internal EpcLookupByUprnStep at the start of the EpcTask will not find an EPC + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasEpcPage.submitHasNoEpc() + val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) + + // Is EPC required - render page + assertThat(isEpcRequiredPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") + isEpcRequiredPage.submitEpcRequired() + val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) + + // EPC Missing - render page + assertThat(epcMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + assertThat(epcMissingPage.continueButton).containsText("Continue") + assertThat(epcMissingPage.warning).isHidden() + epcMissingPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + // Check answers - render page + assertThat(checkAnswersPage.heading).containsText("Check your answers for:") + assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") + // submit + checkAnswersPage.confirm() + val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) + + // Confirmation - render page + val propertyOwnershipCaptor = captor() + verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) + val expectedPropertyRegNum = + RegistrationNumberDataModel.fromRegistrationNumber( + propertyOwnershipCaptor.value.registrationNumber, + ) + assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) + assertFalse(propertyOwnershipCaptor.value.isOccupied) + assertTrue(confirmationPage.whatYouNeedToDoNextHeading.isHidden) + assertTrue(confirmationPage.surveyLink.locator.isVisible) + assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) + + // Check confirmation email + verify(confirmationEmailSender).sendEmail( + "alex.surname@example.com", + PropertyRegistrationConfirmationEmail( + expectedPropertyRegNum.toString(), + "Test address line 1, Testville, EG1 2AB", + absoluteLandlordUrl, + false, + null, + ), + ) - inviteJointLandlordPageWithError.submitEmail("someone.else@example.com") - assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + // Go to dashboard + confirmationPage.goToDashboardLink.clickAndWait() + assertPageIs(page, LandlordDashboardPage::class) + } + + @Test + fun `User can choose to provide compliance certificates later if their property is occupied`(page: Page) { + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert. Submit with no option selected + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasCertPage.submitProvideThisLater() + val provideGasCertLaterPage = assertPageIs(page, ProvideGasCertLaterFormPagePropertyRegistration::class) + + // Provide Gas Cert Later - render page + assertThat(provideGasCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(provideGasCertLaterPage.insetText).containsText("You must upload your gas safety certificate within 28 days") + provideGasCertLaterPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasElectricalCertPage.submitProvideThisLater() + val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) + + // Provide Electrical Cert Later - render page + assertThat(provideElectricalCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat( + provideElectricalCertLaterPage.insetText, + ).containsText("You must upload your electrical safety certificate within 28 days.") + provideElectricalCertLaterPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasEpcPage.submitProvideThisLater() + val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) + + // Provide EPC Later - render page + assertThat(provideEpcLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") + assertThat(provideEpcLaterPage.insetText).containsText( + "To keep the property registered, we need all its compliance certificates within 28 days.", + ) + provideEpcLaterPage.form.submit() + + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + assertPageIs(page, TaskListPagePropertyRegistration::class) + } + + @Test + fun `User can choose to provide compliance certificates later if their property is unoccupied`(page: Page) { + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = false) + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert. Submit with no option selected + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasCertPage.submitProvideThisLater() + val provideGasCertLaterPage = assertPageIs(page, ProvideGasCertLaterFormPagePropertyRegistration::class) + + // Provide Gas Cert Later - render page + assertThat(provideGasCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(provideGasCertLaterPage.insetText).isHidden() + assertTrue( + provideGasCertLaterPage.page + .content() + .contains("You must get a gas safety certificate before a tenant moves in."), + ) + provideGasCertLaterPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasElectricalCertPage.submitProvideThisLater() + val provideElectricalCertLaterPage = assertPageIs(page, ProvideElectricalCertLaterFormPagePropertyRegistration::class) + + // Provide Electrical Cert Later - render page (unoccupied variant) + assertThat(provideElectricalCertLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(provideElectricalCertLaterPage.heading).containsText("Provide your electrical safety certificate later") + assertThat(provideElectricalCertLaterPage.insetText).isHidden() + assertTrue( + provideElectricalCertLaterPage.page + .content() + .contains("You must get an electrical safety certificate before a tenant moves in."), + ) + provideElectricalCertLaterPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasEpcPage.submitProvideThisLater() + val provideEpcLaterPage = assertPageIs(page, ProvideEpcLaterFormPagePropertyRegistration::class) + + // Provide EPC Later - render page + assertThat(provideEpcLaterPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") + assertThat(provideEpcLaterPage.insetText).isHidden() + provideEpcLaterPage.form.submit() + + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + assertPageIs(page, TaskListPagePropertyRegistration::class) + } + + @Test + fun `User can complete the journey with missing compliance certificates for an occupied property`(page: Page) { + // Gas supply page + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert page + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasCertPage.submitHasNoCertificate() + val gasCertMissingPage = assertPageIs(page, GasCertMissingFormPagePropertyRegistration::class) + + // Gas Cert Missing - render page + assertThat(gasCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertMissingPage.heading).containsText("You must get a valid gas safety certificate for this property") + assertThat(gasCertMissingPage.submitButton).containsText("Continue without a valid gas safety certificate") + assertThat(gasCertMissingPage.warning) + .containsText("You could face prosecution if you have tenants in a property without a gas safety certificate") + gasCertMissingPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasNoCert() + val electricalCertMissingPage = assertPageIs(page, ElectricalCertMissingFormPagePropertyRegistration::class) + + assertThat(electricalCertMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat( + electricalCertMissingPage.heading, + ).containsText("You must get a valid electrical safety certificate for this property") + assertThat(electricalCertMissingPage.warning) + .containsText("You could face prosecution if you have tenants in a property without an electrical safety certificate.") + assertThat(electricalCertMissingPage.submitButton).containsText("Continue without a valid electrical safety certificate") + electricalCertMissingPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasEpcPage.submitHasNoEpc() + val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) + + // Is EPC required - render page + assertThat(isEpcRequiredPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") + isEpcRequiredPage.submitEpcRequired() + val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) + + // EPC Missing - render page + assertThat(epcMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + assertThat(epcMissingPage.continueAnywayButton).containsText("Continue anyway") + assertThat( + epcMissingPage.warning, + ).containsText("You can be fined for letting a property that does not meet energy efficiency requirements.") + epcMissingPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") + + // Check Answers - submit to reach Confirm Missing Compliance page + checkAnswersPage.form.submit() + val confirmMissingCompliancePage = assertPageIs(page, ConfirmMissingComplianceFormPagePropertyRegistration::class) + + // Confirm Missing Compliance - render page + assertThat(confirmMissingCompliancePage.heading).containsText("Confirm missing compliance certificates") + assertThat(confirmMissingCompliancePage.warning).isVisible() + assertThat(confirmMissingCompliancePage.form.sectionHeader).containsText("Submit registration") + + // Confirm Missing Compliance - submit + confirmMissingCompliancePage.form.radios.selectValue("true") + confirmMissingCompliancePage.form.submit() + val confirmationPage = assertPageIs(page, ConfirmationPagePropertyRegistration::class) + + // Confirmation - verify record saved + val propertyOwnershipCaptor = captor() + verify(propertyOwnershipRepository).save(propertyOwnershipCaptor.capture()) + val expectedPropertyRegNum = + RegistrationNumberDataModel.fromRegistrationNumber( + propertyOwnershipCaptor.value.registrationNumber, + ) + assertEquals(expectedPropertyRegNum.toString(), confirmationPage.registrationNumberText) + assertTrue(confirmationPage.surveyLink.locator.isVisible) + assertTrue(confirmationPage.goToDashboardLink.locator.isVisible) + } + + @Test + fun `User can complete the journey with expired compliance certificates for an occupied property (epc found by uprn)`(page: Page) { + // Gas supply page + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = true) + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert page + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasCertPage.submitHasCertificate() + var gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page + assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") + gasCertIssueDatePage.submitDate(expiredGasSafetyCertIssueDate) + var gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) + + // Gas Cert Expired - render page then navigate to edit issue date + assertThat(gasCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertExpiredPage.mainHeading).containsText("This gas safety certificate has expired") + assertThat(gasCertExpiredPage.sectionHeading).containsText("You must get a valid gas safety certificate for this property") + assertThat(gasCertExpiredPage.warning) + .containsText("You could face prosecution if you have tenants in a property without a gas safety certificate.") + assertThat(gasCertExpiredPage.submitButton).containsText("Continue without a valid gas safety certificate") + gasCertExpiredPage.changeIssueDateLink.clickAndWait() + gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page, prepopulated with previous value, then submit again + assertThat(gasCertIssueDatePage.form.dayInput).hasValue(expiredGasSafetyCertIssueDate.dayOfMonth.toString()) + assertThat(gasCertIssueDatePage.form.monthInput).hasValue(expiredGasSafetyCertIssueDate.monthNumber.toString()) + assertThat(gasCertIssueDatePage.form.yearInput).hasValue(expiredGasSafetyCertIssueDate.year.toString()) + gasCertIssueDatePage.form.submit() + gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) + + // Back on Gas Cert Expired page - submit + gasCertExpiredPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasEic() + var electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date - render page + assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + electricalCertExpiryDatePage.submitDate(expiredExpiryDate) + var electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) + + // Electrical Cert Expired - render page then check change expiry date link + assertThat(electricalCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(electricalCertExpiredPage.warning) + .containsText("You could face prosecution if you have tenants in a property without an electrical safety certificate.") + assertThat(electricalCertExpiredPage.submitButton).containsText("Continue without a valid electrical safety certificate") + electricalCertExpiredPage.changeExpiryDateLink.clickAndWait() + electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date again - render page, prepopulated with previous value, then submit again + assertThat(electricalCertExpiryDatePage.form.dayInput).hasValue(expiredExpiryDate.dayOfMonth.toString()) + assertThat(electricalCertExpiryDatePage.form.monthInput).hasValue(expiredExpiryDate.monthNumber.toString()) + assertThat(electricalCertExpiryDatePage.form.yearInput).hasValue(expiredExpiryDate.year.toString()) + electricalCertExpiryDatePage.form.submit() + electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) + + // Back on Electrical Cert Expired page - submit + electricalCertExpiredPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep being able to find an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)) + .thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + expiryDate = expiredExpiryDate, + ), + ) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // EpcLookupByUprnStep finds the EPC, so redirects to Check UPRN matched EPCe + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val confirmUprnMatchedEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) + + // Check UPRN matched EPC - submit Yes (accept this expired EPC, which triggers age/rating check internally) + assertThat(confirmUprnMatchedEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + confirmUprnMatchedEpcDetailsPage.submitYes() + val epcExpiryCheckPage = assertPageIs(page, EpcInDateAtStartOfTenancyCheckPagePropertyRegistration::class) + + assertThat(epcExpiryCheckPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + epcExpiryCheckPage.submitEpcExpired() + val epcExpiredPage = assertPageIs(page, EpcExpiredFormPagePropertyRegistration::class) + + // EPC Expired - occupied variant: warning visible, "Continue anyway" button + assertThat(epcExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") + assertThat(epcExpiredPage.warning).isVisible() + assertThat(epcExpiredPage.submitButton).containsText("Continue anyway") + epcExpiredPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") + } + + @Test + fun `User can complete the journey with expired compliance certificates for an unoccupied property (epc not found by uprn)`( + page: Page, + ) { + // Gas supply page + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage(propertyIsOccupied = false) + assertThat(hasGasSupplyPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasSupplyPage.submitHasGasSupply() + val hasGasCertPage = assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + + // Has Gas Cert page + assertThat(hasGasCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasGasCertPage.submitHasCertificate() + var gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page + assertThat(gasCertIssueDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertIssueDatePage.heading).containsText("What’s the issue date on the gas safety certificate?") + gasCertIssueDatePage.submitDate(expiredGasSafetyCertIssueDate) + var gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) + + // Gas Cert Expired - render page then navigate to edit issue date + assertThat(gasCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(gasCertExpiredPage.mainHeading).containsText("This gas safety certificate has expired") + assertThat(gasCertExpiredPage.sectionHeading).containsText("What to do next") + assertThat(gasCertExpiredPage.warning).isHidden() + assertThat(gasCertExpiredPage.submitButton).containsText("Save and continue") + gasCertExpiredPage.changeIssueDateLink.clickAndWait() + gasCertIssueDatePage = assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + + // Gas Cert Issue Date - render page, prepopulated with previous value, then submit again + assertThat(gasCertIssueDatePage.form.dayInput).hasValue(expiredGasSafetyCertIssueDate.dayOfMonth.toString()) + assertThat(gasCertIssueDatePage.form.monthInput).hasValue(expiredGasSafetyCertIssueDate.monthNumber.toString()) + assertThat(gasCertIssueDatePage.form.yearInput).hasValue(expiredGasSafetyCertIssueDate.year.toString()) + gasCertIssueDatePage.form.submit() + gasCertExpiredPage = assertPageIs(page, GasCertExpiredFormPagePropertyRegistration::class) + + // Back on Gas Cert Expired page - submit + gasCertExpiredPage.form.submit() + val checkGasSafetyAnswersPage = assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + + // Check Gas Safety Answers - render page + assertThat(checkGasSafetyAnswersPage.heading).containsText("Gas safety certificate") + + checkGasSafetyAnswersPage.form.submit() + val taskListPageAfterGasSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterGasSafety.clickRegisterTaskWithName("Electrical safety certificate") + val hasElectricalCertPage = assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + + // Has Electrical Cert - render page + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasElectricalCertPage.heading).containsText("Which electrical safety certificate do you have for this property?") + hasElectricalCertPage.submitHasEic() + var electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date - render page + assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + electricalCertExpiryDatePage.submitDate(expiredExpiryDate) + var electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) + + // Electrical Cert Expired - render page then check change expiry date link + assertThat(electricalCertExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(electricalCertExpiredPage.warning).isHidden() + assertThat(electricalCertExpiredPage.submitButton).containsText("Save and continue") + electricalCertExpiredPage.changeExpiryDateLink.clickAndWait() + electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date again - render page, prepopulated with previous value, then submit again + assertThat(electricalCertExpiryDatePage.form.dayInput).hasValue(expiredExpiryDate.dayOfMonth.toString()) + assertThat(electricalCertExpiryDatePage.form.monthInput).hasValue(expiredExpiryDate.monthNumber.toString()) + assertThat(electricalCertExpiryDatePage.form.yearInput).hasValue(expiredExpiryDate.year.toString()) + electricalCertExpiryDatePage.form.submit() + electricalCertExpiredPage = assertPageIs(page, ElectricalCertExpiredFormPagePropertyRegistration::class) + + // Back on Electrical Cert Expired page - submit + electricalCertExpiredPage.form.submit() + val checkElectricalSafetyAnswersPage = assertPageIs(page, CheckElectricalSafetyAnswersFormPagePropertyRegistration::class) + + // Setup EpcLookupByUprnStep NOT finding an EPC for this property when the next step submits + whenever(epcRegisterClient.getByUprn(uprnForSelectedAddress)).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + // Check Electrical Safety Answers - render page + assertThat(checkElectricalSafetyAnswersPage.heading).containsText("Electrical safety certificate") + checkElectricalSafetyAnswersPage.form.submit() + val taskListPageAfterElectricalSafety = assertPageIs(page, TaskListPagePropertyRegistration::class) + + // The internal EpcLookupByUprnStep at the start of the EpcTask does not find an EPC + taskListPageAfterElectricalSafety.clickRegisterTaskWithName("Energy performance certificate (EPC)") + val hasEpcPage = assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + + // Has EPC - render page + assertThat(hasEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasEpcPage.submitHasEpc() + val findYourEpcPage = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) + + // EPC Search - render page + assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + whenever(epcRegisterClient.getByRrn(CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER)) + .thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + certificateNumber = CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER, + expiryDate = expiredExpiryDate, + latestCertificateNumberForThisProperty = CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER, + ), + ) + findYourEpcPage.submitCurrentEpcNumberWhichIsExpired() + val confirmEpcDetailsPage = assertPageIs(page, ConfirmEpcDetailsRetrievedByCertificateNumberPagePropertyRegistration::class) + + // Check Matched EPC - render page + assertThat(confirmEpcDetailsPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + val expectedExpiryDate = + expiredExpiryDate + .toJavaLocalDate() + .format(DateTimeFormatter.ofPattern("d MMMM yyyy")) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.addressRow.value).containsText(MockEpcData.defaultSingleLineAddress) + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.energyEfficiencyRatingRow.value).containsText("C") + assertThat(confirmEpcDetailsPage.summaryCard.summaryList.expiryDateRow.value).containsText(expectedExpiryDate) + assertThat( + confirmEpcDetailsPage.summaryCard.summaryList.certificateNumberRow.value, + ).containsText(CURRENT_EXPIRED_EPC_CERTIFICATE_NUMBER) + confirmEpcDetailsPage.submitYes() + val epcExpiredPage = assertPageIs(page, EpcExpiredFormPagePropertyRegistration::class) + + // EPC Expired - unoccupied variant: no warning, "Continue" button + assertThat(epcExpiredPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") + assertThat(epcExpiredPage.warning).isHidden() + assertThat(epcExpiredPage.submitButton).containsText("Continue") + epcExpiredPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + val taskListPageAfterEpc = assertPageIs(page, TaskListPagePropertyRegistration::class) + taskListPageAfterEpc.clickCheckAndSubmitTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + assertThat(checkAnswersPage.sectionHeader).containsText("Section 2 of 2 — Check and submit your property details") + } + + @Test + fun `The Electrical Safety task can be completed by the user uploaded an eicr`(page: Page) { + // Skip to Has Electrical Cert page and submit "Yes" + val hasElectricalCertPage = navigator.skipToPropertyRegistrationHasElectricalCertPage() + assertThat(hasElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasElectricalCertPage.submitHasEicr() + val electricalCertExpiryDatePage = assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + + // Electrical Cert Expiry Date - render page + assertThat(electricalCertExpiryDatePage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat( + electricalCertExpiryDatePage.heading, + ).containsText("What’s the expiry date on the Electrical Installation Condition Report?") + electricalCertExpiryDatePage.submitDate(validExpiryDate) + val uploadElectricalCertPage = assertPageIs(page, UploadElectricalCertFormPagePropertyRegistration::class) + + // Upload Electrical Cert - render page + assertThat(uploadElectricalCertPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(uploadElectricalCertPage.heading).containsText("Upload the Electrical Installation Condition Report (EICR)") + uploadElectricalCertPage.uploadElectricalCertificate(Path.of("src/test/resources/test-files/blank.png")) + + // Check Electrical Safety Answers - EICR variant verified by heading text + } + + @Test + fun `The EPC task can be completed when FindYourEpc finds a superseded epc`(page: Page) { + // Skip to Find Your EPC page and submit "Superseded EPC Found" + val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() + assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + whenever(epcRegisterClient.getByRrn(SUPERSEDED_EPC_CERTIFICATE_NUMBER)).thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + certificateNumber = SUPERSEDED_EPC_CERTIFICATE_NUMBER, + expiryDate = MockEpcData.expiryDateInThePast, + latestCertificateNumberForThisProperty = CURRENT_EPC_CERTIFICATE_NUMBER, + ), + ) + whenever(epcRegisterClient.getByRrn(CURRENT_EPC_CERTIFICATE_NUMBER)).thenReturn( + MockEpcData.createEpcRegisterClientEpcFoundResponse( + certificateNumber = CURRENT_EPC_CERTIFICATE_NUMBER, + ), + ) + findYourEpcPage.submitSupersededEpcNumber() + val epcSupersededPage = assertPageIs(page, EpcSuperseededFormPagePropertyRegistration::class) + + // Check details of superseded and latest epc - render page + assertThat(epcSupersededPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + epcSupersededPage.submitContinueWithLatest() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + assertPageIs(page, TaskListPagePropertyRegistration::class) + } + + @Test + fun `The EPC task can be completed when FindYourEpc finds no epc and it is missing`(page: Page) { + // Skip to Find Your EPC page and submit "No EPC Found" + val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() + assertThat(findYourEpcPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + whenever( + epcRegisterClient.getByRrn(NONEXISTENT_EPC_CERTIFICATE_NUMBER), + ).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + findYourEpcPage.submitNonexistentEpcNumber() + val epcNotFoundPage = assertPageIs(page, EpcNotFoundFormPagePropertyRegistration::class) + + // EPC not found - render page + assertThat(epcNotFoundPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(epcNotFoundPage.heading).containsText("We could not find your EPC") + assertThat(epcNotFoundPage.certificateNumberText).containsText(NONEXISTENT_EPC_CERTIFICATE_NUMBER) + assertThat(epcNotFoundPage.searchAgainLink).isVisible() + + // Click 'search again' to return to Find Your EPC and re-submit not found + epcNotFoundPage.searchAgainLink.click() + val findYourEpcPageAgain = assertPageIs(page, FindYourEpcFormPagePropertyRegistration::class) + assertThat(findYourEpcPageAgain.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + whenever( + epcRegisterClient.getByRrn(NONEXISTENT_EPC_CERTIFICATE_NUMBER), + ).thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + findYourEpcPageAgain.submitNonexistentEpcNumber() + assertPageIs(page, EpcNotFoundFormPagePropertyRegistration::class).form.submit() + + val isEpcRequiredPage = assertPageIs(page, IsEpcRequiredFormPagePropertyRegistration::class) + + // Is EPC required - render page + assertThat(isEpcRequiredPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(isEpcRequiredPage.heading).containsText("Is an EPC required to let this property?") + isEpcRequiredPage.submitEpcRequired() + val epcMissingPage = assertPageIs(page, EpcMissingFormPagePropertyRegistration::class) + + // EPC Missing - render page + assertThat(epcMissingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + assertThat(epcMissingPage.continueAnywayButton).containsText("Continue anyway") + assertThat( + epcMissingPage.warning, + ).containsText("You can be fined for letting a property that does not meet energy efficiency requirements.") + epcMissingPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + checkEpcAnswersPage.form.submit() + assertPageIs(page, TaskListPagePropertyRegistration::class) + } + + @Test + fun `User can navigate the MEES flow when they have a MEES exemption`(page: Page) { + val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() + + // Has MEES Exemption - render page + assertThat(hasMeesExemptionPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(hasMeesExemptionPage.heading).containsText("You need a registered energy efficiency exemption to let this property") + hasMeesExemptionPage.submitHasMeesExemption() + val meesExemptionPage = assertPageIs(page, MeesExemptionFormPagePropertyRegistration::class) + + // MEES Exemption - select exemption reason + assertThat(meesExemptionPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + meesExemptionPage.submitExemptionReason(MeesExemptionReason.HIGH_COST) + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + } + + @Test + fun `User can navigate the MEES flow when they do not have a MEES exemption`(page: Page) { + val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() + + // Has MEES Exemption - submit no exemption + assertThat(hasMeesExemptionPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + hasMeesExemptionPage.submitHasNoMeesExemption() + val lowEnergyRatingPage = assertPageIs(page, LowEnergyRatingFormPagePropertyRegistration::class) + + // Low Energy Rating - render page + assertThat(lowEnergyRatingPage.sectionHeader).containsText(propertyRegistrationSectionHeader) + assertThat(lowEnergyRatingPage.heading).containsText("This property does not meet energy efficiency requirements for letting") + lowEnergyRatingPage.form.submit() + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + } + + @Test + fun `User can navigate the EPC exemption flow`(page: Page) { + val epcExemptionPage = navigator.skipToPropertyRegistrationEpcExemptionPage() + + // EPC Exemption - select exemption reason + assertThat(epcExemptionPage.form.sectionHeader).containsText(propertyRegistrationSectionHeader) + epcExemptionPage.submitExemptionReason(EpcExemptionReason.PROTECTED_ARCHITECTURAL_OR_HISTORICAL_MERIT) + val checkEpcAnswersPage = assertPageIs(page, CheckEpcAnswersFormPagePropertyRegistration::class) + + // Check EPC Answers - render page + assertThat(checkEpcAnswersPage.heading).containsText("Energy performance certificate (EPC)") + } + + @Test + fun `task list back link navigates to start page after entering from start page`(page: Page) { + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + val taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.backLink.clickAndWait() + assertPageIs(page, RegisterPropertyStartPage::class) + } + + @Test + fun `task list back link navigates to start page after entering from start page and returning from a task`(page: Page) { + val registerPropertyStartPage = navigator.goToPropertyRegistrationStartPage() + registerPropertyStartPage.startButton.clickAndWait() + var taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.clickRegisterTaskWithName("Property address") + assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + + val backLink = BackLink.default(page) + backLink.clickAndWait() + taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) + + taskListPage.backLink.clickAndWait() + assertPageIs(page, RegisterPropertyStartPage::class) + } + + @Test + fun `numeric values with leading zeros are displayed without leading zeros on the CYA page`(page: Page) { + val checkAnswersPage = + navigator.skipToPropertyRegistrationCheckAnswersPageOccupied( + households = 2, + people = 4, + bedrooms = 3, + rentAmount = "0000000.1", + ) + + assertThat(checkAnswersPage.summaryList.rentAmountRow.value).containsText("£0.1") + assertThat(checkAnswersPage.summaryList.numberOfHouseholdsRow.value).containsText("2") + assertThat(checkAnswersPage.summaryList.numberOfTenantsRow.value).containsText("4") + assertThat(checkAnswersPage.summaryList.numberOfBedroomsRow.value).containsText("3") + } + + @Test + fun `CYA joint landlords row shows a change link to the check joint landlords page when landlords are invited`(page: Page) { + val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPageWithJointLandlords() + + val changeLink = + checkAnswersPage.summaryList.jointLandlordsInvitationsRow.actions + .getActionLink("Change") + assertThat(changeLink).isVisible() + + changeLink.clickAndWait() + val checkJointLandlordsPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordsPage.summaryList.firstRow.value).containsText("email@address.com") + } + + @Test + fun `CYA joint landlords row shows a change link to the has joint landlords page when there are no joint landlords`(page: Page) { + val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() + + val changeLink = + checkAnswersPage.summaryList.jointLandlordsAreThereRow.actions + .getActionLink("Change") + assertThat(changeLink).isVisible() + + changeLink.clickAndWait() + assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + } + + @Test + fun `a landlord cannot invite themselves as a joint landlord`(page: Page) { + val inviteJointLandlordPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + + inviteJointLandlordPage.submitEmail("alex.surname@example.com") + + val inviteJointLandlordPageWithError = assertPageIs(page, InviteJointLandlordFormPagePropertyRegistration::class) + assertThat(inviteJointLandlordPageWithError.form.getErrorMessage()) + .containsText("You cannot invite yourself as a joint landlord") + + inviteJointLandlordPageWithError.submitEmail("someone.else@example.com") + assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + } } } diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationSinglePageTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationSinglePageTests.kt index 3db22916fd..ee228fe96b 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationSinglePageTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationSinglePageTests.kt @@ -65,1601 +65,3186 @@ class PropertyRegistrationSinglePageTests : IntegrationTestWithImmutableData("da @MockitoSpyBean private lateinit var savedJourneyStateRepository: SavedJourneyStateRepository - @BeforeEach - fun disableRestructureFlag() { - // These tests exercise the legacy property registration task list, so disable the restructure flag - // which is enabled by default in the integration config. - featureFlagManager.disableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - } - @Nested - inner class TaskListStep { - @Test - fun `Completing preceding steps will show a task as not started and completed steps as complete`(page: Page) { - navigator.skipToPropertyRegistrationHasJointLandlordsPage() - val taskListPage = navigator.goToPropertyRegistrationTaskList() - assert(taskListPage.taskHasStatus("Property address", "Complete")) - assert(taskListPage.taskHasStatus("Property type", "Complete")) - assert(taskListPage.taskHasStatus("How you own the property", "Complete")) - assert(taskListPage.taskHasStatus("If the property has a license", "Complete")) - assert(taskListPage.taskHasStatus("Tenancy and rental information", "Complete")) - assert(taskListPage.taskHasStatus("Invite joint landlords", "Not started")) - assert(taskListPage.taskHasStatus("Gas safety certificate", "Cannot start yet")) - assert(taskListPage.taskHasStatus("Electrical safety certificate", "Cannot start yet")) - assert(taskListPage.taskHasStatus("Energy performance certificate (EPC)", "Cannot start yet")) - } - - @Test - fun `EPC task (starting with an internal step) shows as Not Started when the user is on the first step they see`(page: Page) { - navigator.skipToPropertyRegistrationHasEpcPage() - val taskListPage = navigator.goToPropertyRegistrationTaskList() - assert(taskListPage.taskHasStatus("Energy performance certificate (EPC)", "Not started")) - } - - @Test - fun `Completing first step of a task will show a task as in progress and completed steps as complete`(page: Page) { - navigator.skipToPropertyRegistrationRentFrequencyPage() - val taskListPage = navigator.goToPropertyRegistrationTaskList() - assert(taskListPage.taskHasStatus("Property address", "Complete")) - assert(taskListPage.taskHasStatus("Property type", "Complete")) - assert(taskListPage.taskHasStatus("How you own the property", "Complete")) - assert(taskListPage.taskHasStatus("If the property has a license", "Complete")) - assert(taskListPage.taskHasStatus("Tenancy and rental information", "In progress")) - assert(taskListPage.taskHasStatus("Invite joint landlords", "Cannot start yet")) - assert(taskListPage.taskHasStatus("Gas safety certificate", "Cannot start yet")) - assert(taskListPage.taskHasStatus("Electrical safety certificate", "Cannot start yet")) - assert(taskListPage.taskHasStatus("Energy performance certificate (EPC)", "Cannot start yet")) + inner class RestructureAndSkippingEnabled { + @BeforeEach + fun enableRestructureAndSkippingFlag() { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) } - } - @Nested - inner class LookupAddressAndNoAddressFoundSteps { - @Test - fun `Submitting with empty data fields returns an error`(page: Page) { - val lookupAddressPage = navigator.goToPropertyRegistrationLookupAddressPage() - lookupAddressPage.clearForm() // There may be form answers in the journey state - lookupAddressPage.form.submit() - assertThat(lookupAddressPage.form.getErrorMessage("postcode")).containsText("Enter a postcode") - assertThat(lookupAddressPage.form.getErrorMessage("houseNameOrNumber")).containsText("Enter a house name or number") - } - - @Test - fun `If no English addresses are found, user can search again or enter address manually via the No Address Found step`(page: Page) { - // Lookup address finds no English results - val houseNumber = "NOT A HOUSE NUMBER" - val postcode = "NOT A POSTCODE" - var lookupAddressPage = navigator.goToPropertyRegistrationLookupAddressPage() - lookupAddressPage.submitPostcodeAndBuildingNameOrNumber(postcode, houseNumber) - - // redirect to noAddressFoundPage - var noAddressFoundPage = assertPageIs(page, NoAddressFoundFormPagePropertyRegistration::class) - BaseComponent - .assertThat(noAddressFoundPage.heading) - .containsText("No matching address in England found for $postcode and $houseNumber") - - // Search Again - noAddressFoundPage.searchAgain.clickAndWait() - lookupAddressPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) - lookupAddressPage.submitPostcodeAndBuildingNameOrNumber(postcode, houseNumber) - - // Submit no address found page - noAddressFoundPage = assertPageIs(page, NoAddressFoundFormPagePropertyRegistration::class) - noAddressFoundPage.form.submit() - assertPageIs(page, ManualAddressFormPagePropertyRegistration::class) - } - } + @Nested + inner class TaskListStep { + @Test + fun `Completing preceding steps will show a task as not started and completed steps as complete`(page: Page) { + navigator.skipToPropertyRegistrationHasJointLandlordsPage() + val taskListPage = navigator.goToPropertyRegistrationTaskList() + assert(taskListPage.getAboutYourPropertyTask("Property details").statusText.contains("Complete")) + assert(taskListPage.getAboutYourPropertyTask("Ownership and landlords").statusText.contains("In progress")) + assert(taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.contains("Cannot start yet")) + assert(taskListPage.getRentedOutTask("Tell us if your property needs a license").statusText.contains("Cannot start yet")) + assert(taskListPage.getRentedOutTask("Gas safety certificate").statusText.contains("Cannot start yet")) + assert(taskListPage.getRentedOutTask("Electrical safety certificate").statusText.contains("Cannot start yet")) + assert(taskListPage.getRentedOutTask("Energy performance certificate (EPC)").statusText.contains("Cannot start yet")) + assert(taskListPage.getRentedOutTask("Tenancy details").statusText.contains("Cannot start yet")) + assert(taskListPage.getSubmitYourRegistrationTask("Check and submit your answers").statusText.contains("Cannot start yet")) + } - @Nested - inner class SelectAddressStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage() - selectAddressPage.form.submit() - assertThat(selectAddressPage.form.getErrorMessage()).containsText("Select an address") - } + @Test + fun `EPC task (starting with an internal step) shows as Not Started when the user is on the first step they see`(page: Page) { + navigator.skipToPropertyRegistrationHasEpcPage() + val taskListPage = navigator.goToPropertyRegistrationTaskList() + assert(taskListPage.getRentedOutTask("Energy performance certificate (EPC)").statusText.contains("Not started")) + } - @Test - fun `Clicking Search Again navigates to the previous step`(page: Page) { - val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage() - selectAddressPage.searchAgain.clickAndWait() - assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + @Test + fun `Completing first step of a task will show a task as in progress and completed steps as complete`(page: Page) { + navigator.skipToPropertyRegistrationHasGasCertPage() + val taskListPage = navigator.goToPropertyRegistrationTaskList() + assert(taskListPage.getAboutYourPropertyTask("Property details").statusText.contains("Complete")) + assert(taskListPage.getAboutYourPropertyTask("Ownership and landlords").statusText.contains("Complete")) + assert(taskListPage.getAboutYourPropertyTask("Tell us if your property’s occupied").statusText.contains("Complete")) + assert(taskListPage.getRentedOutTask("Tell us if your property needs a license").statusText.contains("Complete")) + assert(taskListPage.getRentedOutTask("Gas safety certificate").statusText.contains("In progress")) + assert(taskListPage.getRentedOutTask("Electrical safety certificate").statusText.contains("Cannot start yet")) + assert(taskListPage.getRentedOutTask("Energy performance certificate (EPC)").statusText.contains("Cannot start yet")) + assert(taskListPage.getRentedOutTask("Tenancy details").statusText.contains("Cannot start yet")) + assert(taskListPage.getSubmitYourRegistrationTask("Check and submit your answers").statusText.contains("Cannot start yet")) + } } - @Test - fun `Selecting an already-registered address navigates to the AlreadyRegistered step`(page: Page) { - val alreadyRegisteredAddress = AddressDataModel("1 Example Road", uprn = 1123456) - val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage(listOf(alreadyRegisteredAddress)) - selectAddressPage.selectAddressAndSubmit(alreadyRegisteredAddress.singleLineAddress) - assertPageIs(page, AlreadyRegisteredFormPagePropertyRegistration::class) - } - } + @Nested + inner class LookupAddressAndNoAddressFoundSteps { + @Test + fun `Submitting with empty data fields returns an error`(page: Page) { + val lookupAddressPage = navigator.goToPropertyRegistrationLookupAddressPage() + lookupAddressPage.clearForm() // There may be form answers in the journey state + lookupAddressPage.form.submit() + assertThat(lookupAddressPage.form.getErrorMessage("postcode")).containsText("Enter a postcode") + assertThat(lookupAddressPage.form.getErrorMessage("houseNameOrNumber")).containsText("Enter a house name or number") + } - @Nested - inner class ManualAddressEntryStep { - @Test - fun `Submitting empty data fields returns errors`(page: Page) { - val manualAddressPage = navigator.skipToPropertyRegistrationManualAddressPage() - manualAddressPage.submitAddress() - assertThat(manualAddressPage.form.getErrorMessage("addressLineOne")) - .containsText("Enter the first line of an address, typically the building and street") - assertThat(manualAddressPage.form.getErrorMessage("townOrCity")).containsText("Enter town or city") - assertThat(manualAddressPage.form.getErrorMessage("postcode")).containsText("Enter postcode") + @Test + fun `If no English addresses are found, user can search again or enter address manually via the No Address Found step`( + page: Page, + ) { + // Lookup address finds no English results + val houseNumber = "NOT A HOUSE NUMBER" + val postcode = "NOT A POSTCODE" + var lookupAddressPage = navigator.goToPropertyRegistrationLookupAddressPage() + lookupAddressPage.submitPostcodeAndBuildingNameOrNumber(postcode, houseNumber) + + // redirect to noAddressFoundPage + var noAddressFoundPage = assertPageIs(page, NoAddressFoundFormPagePropertyRegistration::class) + BaseComponent + .assertThat(noAddressFoundPage.heading) + .containsText("No matching address in England found for $postcode and $houseNumber") + + // Search Again + noAddressFoundPage.searchAgain.clickAndWait() + lookupAddressPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + lookupAddressPage.submitPostcodeAndBuildingNameOrNumber(postcode, houseNumber) + + // Submit no address found page + noAddressFoundPage = assertPageIs(page, NoAddressFoundFormPagePropertyRegistration::class) + noAddressFoundPage.form.submit() + assertPageIs(page, ManualAddressFormPagePropertyRegistration::class) + } } - } - @Nested - inner class SelectLocalCouncilStep { - @Test - fun `Submitting without selecting an LA return an error`(page: Page) { - val selectLocalCouncilPage = navigator.skipToPropertyRegistrationSelectLocalCouncilPage() - selectLocalCouncilPage.form.submit() - assertThat(selectLocalCouncilPage.form.getErrorMessage("localCouncilId")) - .containsText("Select a local council to continue") - } - } + @Nested + inner class SelectAddressStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage() + selectAddressPage.form.submit() + assertThat(selectAddressPage.form.getErrorMessage()).containsText("Select an address") + } - @Nested - inner class PropertyTypeStep { - @Test - fun `Submitting with no propertyType selected returns an error`(page: Page) { - val propertyTypePage = navigator.skipToPropertyRegistrationPropertyTypePage() - propertyTypePage.form.submit() - assertThat(propertyTypePage.form.getErrorMessage()).containsText("Select the type of property") - } + @Test + fun `Clicking Search Again navigates to the previous step`(page: Page) { + val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage() + selectAddressPage.searchAgain.clickAndWait() + assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + } - @Test - fun `Submitting with the Other propertyType selected but an empty customPropertyType field returns an error`(page: Page) { - val propertyTypePage = navigator.skipToPropertyRegistrationPropertyTypePage() - propertyTypePage.submitCustomPropertyType("") - assertThat(propertyTypePage.form.getErrorMessage()).containsText("Enter the property type") + @Test + fun `Selecting an already-registered address navigates to the AlreadyRegistered step`(page: Page) { + val alreadyRegisteredAddress = AddressDataModel("1 Example Road", uprn = 1123456) + val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage(listOf(alreadyRegisteredAddress)) + selectAddressPage.selectAddressAndSubmit(alreadyRegisteredAddress.singleLineAddress) + assertPageIs(page, AlreadyRegisteredFormPagePropertyRegistration::class) + } } - } - @Nested - inner class OwnershipTypeStep { - @Test - fun `Submitting with no ownershipType selected returns an error`(page: Page) { - val ownershipTypePage = navigator.skipToPropertyRegistrationOwnershipTypePage() - ownershipTypePage.form.submit() - assertThat(ownershipTypePage.form.getErrorMessage()).containsText("Select the ownership type") + @Nested + inner class ManualAddressEntryStep { + @Test + fun `Submitting empty data fields returns errors`(page: Page) { + val manualAddressPage = navigator.skipToPropertyRegistrationManualAddressPage() + manualAddressPage.submitAddress() + assertThat(manualAddressPage.form.getErrorMessage("addressLineOne")) + .containsText("Enter the first line of an address, typically the building and street") + assertThat(manualAddressPage.form.getErrorMessage("townOrCity")).containsText("Enter town or city") + assertThat(manualAddressPage.form.getErrorMessage("postcode")).containsText("Enter postcode") + } } - } - @Nested - inner class LicensingTypeStep { - @Test - fun `Submitting with no licensingType selected returns an error`(page: Page) { - val licensingTypePage = navigator.skipToPropertyRegistrationLicensingTypePage() - licensingTypePage.form.submit() - assertThat(licensingTypePage.form.getErrorMessage()).containsText("Select the type of licensing for the property") - } - - @Test - fun `Submitting with an HMO mandatory licence redirects to the next step`(page: Page) { - val licensingTypePage = navigator.skipToPropertyRegistrationLicensingTypePage() - licensingTypePage.submitLicensingType(LicensingType.HMO_MANDATORY_LICENCE) - val licenseNumberPage = assertPageIs(page, HmoMandatoryLicenceFormPagePropertyRegistration::class) - BaseComponent - .assertThat(licenseNumberPage.form.sectionHeader) - .containsText("Section 1 of 2 — Add property details") - } - - @Test - fun `Submitting with an HMO additional licence redirects to the next step`(page: Page) { - val licensingTypePage = navigator.skipToPropertyRegistrationLicensingTypePage() - licensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) - val licenseNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyRegistration::class) - BaseComponent - .assertThat(licenseNumberPage.form.sectionHeader) - .containsText("Section 1 of 2 — Add property details") - } - - @Test - fun `Submitting provide this later on licensing routes to occupied provide licensing later page`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) - - val taskListPage = - navigator.goToRestructuredPropertyRegistrationTaskList( - PropertyStateSessionBuilder - .beforePropertyRegistrationOwnershipType() - .withBedrooms() - .withOwnershipType() - .withHasNoJointLandlords() - .withOccupancyStatus(true), - ) - taskListPage.clickRentedOutTaskWithName("Tell us if your property needs a license") - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - assertThat(licensingTypePage.provideThisLaterButton).isVisible() + @Nested + inner class SelectLocalCouncilStep { + @Test + fun `Submitting without selecting an LA return an error`(page: Page) { + val selectLocalCouncilPage = navigator.skipToPropertyRegistrationSelectLocalCouncilPage() + selectLocalCouncilPage.form.submit() + assertThat(selectLocalCouncilPage.form.getErrorMessage("localCouncilId")) + .containsText("Select a local council to continue") + } + } - licensingTypePage.submitProvideThisLater() - val provideLicensingLaterPage = assertPageIs(page, ProvideLicensingLaterFormPagePropertyRegistration::class) + @Nested + inner class PropertyTypeStep { + @Test + fun `Submitting with no propertyType selected returns an error`(page: Page) { + val propertyTypePage = navigator.skipToPropertyRegistrationPropertyTypePage() + propertyTypePage.form.submit() + assertThat(propertyTypePage.form.getErrorMessage()).containsText("Select the type of property") + } - BaseComponent - .assertThat(provideLicensingLaterPage.heading) - .containsText("Provide details about property licensing later") - BaseComponent.assertThat(provideLicensingLaterPage.insetText).isVisible() + @Test + fun `Submitting with the Other propertyType selected but an empty customPropertyType field returns an error`(page: Page) { + val propertyTypePage = navigator.skipToPropertyRegistrationPropertyTypePage() + propertyTypePage.submitCustomPropertyType("") + assertThat(propertyTypePage.form.getErrorMessage()).containsText("Enter the property type") + } } - @Test - fun `Submitting provide this later on licensing routes to unoccupied provide licensing later page`(page: Page) { - featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + @Nested + inner class OwnershipTypeStep { + @Test + fun `Submitting with no ownershipType selected returns an error`(page: Page) { + val ownershipTypePage = navigator.skipToPropertyRegistrationOwnershipTypePage() + ownershipTypePage.form.submit() + assertThat(ownershipTypePage.form.getErrorMessage()).containsText("Select the ownership type") + } + } - val taskListPage = - navigator.goToRestructuredPropertyRegistrationTaskList( - PropertyStateSessionBuilder - .beforePropertyRegistrationOwnershipType() - .withBedrooms() - .withOwnershipType() - .withHasNoJointLandlords() - .withOccupancyStatus(false), - ) - taskListPage.clickRentedOutTaskWithName("Tell us if your property needs a license") - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - assertThat(licensingTypePage.provideThisLaterButton).isVisible() + @Nested + inner class LicensingTypeStep { + @Test + fun `Submitting with no licensingType selected returns an error`(page: Page) { + val licensingTypePage = navigator.skipToPropertyRegistrationOccupiedLicensingTypePage() + licensingTypePage.form.submit() + assertThat(licensingTypePage.form.getErrorMessage()).containsText("Select the type of licensing for the property") + } - licensingTypePage.submitProvideThisLater() - val provideLicensingLaterPage = assertPageIs(page, ProvideLicensingLaterFormPagePropertyRegistration::class) + @Test + fun `Submitting with an HMO mandatory licence redirects to the next step`(page: Page) { + val licensingTypePage = navigator.skipToPropertyRegistrationOccupiedLicensingTypePage() + licensingTypePage.submitLicensingType(LicensingType.HMO_MANDATORY_LICENCE) + val licenseNumberPage = assertPageIs(page, HmoMandatoryLicenceFormPagePropertyRegistration::class) + BaseComponent + .assertThat(licenseNumberPage.form.sectionHeader) + .containsText("Tell us if your property needs a license") + } - BaseComponent - .assertThat(provideLicensingLaterPage.heading) - .containsText("Provide details about property licensing later") - BaseComponent.assertThat(provideLicensingLaterPage.insetText).isHidden() - } - } + @Test + fun `Submitting with an HMO additional licence redirects to the next step`(page: Page) { + val licensingTypePage = navigator.skipToPropertyRegistrationOccupiedLicensingTypePage() + licensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) + val licenseNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyRegistration::class) + BaseComponent + .assertThat(licenseNumberPage.form.sectionHeader) + .containsText("Tell us if your property needs a license") + } - @Nested - inner class SelectiveLicenceStep { - @Test - fun `Submitting with no licence number returns an error`(page: Page) { - val selectiveLicencePage = navigator.skipToPropertyRegistrationSelectiveLicencePage() - selectiveLicencePage.form.submit() - assertThat(selectiveLicencePage.form.getErrorMessage()).containsText("Enter the selective licence number") - } - - @Test - fun `Submitting with a very long licence number returns an error`(page: Page) { - val selectiveLicencePage = navigator.skipToPropertyRegistrationSelectiveLicencePage() - val aVeryLongString = - "This string is very long, so long that it is not feasible that it is a real licence number " + - "- therefore if it is submitted there will in fact be an error rather than a successful submission." + - " It is actually quite difficult for a string to be long enough to trigger this error, because the" + - " maximum length has been selected to be permissive of id numbers we do not expect while still having " + - "a cap reachable with a little effort." - selectiveLicencePage.submitLicenseNumber(aVeryLongString) - assertThat(selectiveLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") - } - } + @Test + fun `Submitting provide this later on licensing routes to occupied provide licensing later page`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + val taskListPage = + navigator.goToRestructuredPropertyRegistrationTaskList( + PropertyStateSessionBuilder + .beforePropertyRegistrationOwnershipType() + .withBedrooms() + .withOwnershipType() + .withHasNoJointLandlords() + .withOccupancyStatus(true), + ) + taskListPage.clickRentedOutTaskWithName("Tell us if your property needs a license") + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + assertThat(licensingTypePage.provideThisLaterButton).isVisible() + + licensingTypePage.submitProvideThisLater() + val provideLicensingLaterPage = assertPageIs(page, ProvideLicensingLaterFormPagePropertyRegistration::class) - @Nested - inner class HmoMandatoryLicenceStep { - @Test - fun `Submitting with a licence number redirects to the next step`(page: Page) { - val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationHmoMandatoryLicencePage() - hmoMandatoryLicencePage.submitLicenseNumber("licence number") - assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - } - - @Test - fun `Submitting with no licence number returns an error`(page: Page) { - val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationHmoMandatoryLicencePage() - hmoMandatoryLicencePage.form.submit() - assertThat(hmoMandatoryLicencePage.form.getErrorMessage()).containsText("Enter the HMO Mandatory licence number") - } - - @Test - fun `Submitting with a very long licence number returns an error`(page: Page) { - val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationHmoMandatoryLicencePage() - val aVeryLongString = - "This string is very long, so long that it is not feasible that it is a real licence number " + - "- therefore if it is submitted there will in fact be an error rather than a successful submission." + - " It is actually quite difficult for a string to be long enough to trigger this error, because the" + - " maximum length has been selected to be permissive of id numbers we do not expect while still having " + - "a cap reachable with a little effort." - hmoMandatoryLicencePage.submitLicenseNumber(aVeryLongString) - assertThat(hmoMandatoryLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") - } - } + BaseComponent + .assertThat(provideLicensingLaterPage.heading) + .containsText("Provide details about property licensing later") + BaseComponent.assertThat(provideLicensingLaterPage.insetText).isVisible() + } - @Nested - inner class HmoAdditionalLicenceStep { - @Test - fun `Submitting with a licence number redirects to the next step`(page: Page) { - val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationHmoAdditionalLicencePage() - hmoAdditionalLicencePage.submitLicenseNumber("licence number") - assertPageIs(page, OccupancyFormPagePropertyRegistration::class) - } - - @Test - fun `Submitting with no licence number returns an error`(page: Page) { - val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationHmoAdditionalLicencePage() - hmoAdditionalLicencePage.form.submit() - assertThat(hmoAdditionalLicencePage.form.getErrorMessage()).containsText("Enter the HMO additional licence number") - } - - @Test - fun `Submitting with a very long licence number returns an error`(page: Page) { - val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationHmoAdditionalLicencePage() - val aVeryLongString = - "This string is very long, so long that it is not feasible that it is a real licence number " + - "- therefore if it is submitted there will in fact be an error rather than a successful submission." + - " It is actually quite difficult for a string to be long enough to trigger this error, because the" + - " maximum length has been selected to be permissive of id numbers we do not expect while still having " + - "a cap reachable with a little effort." - hmoAdditionalLicencePage.submitLicenseNumber(aVeryLongString) - assertThat(hmoAdditionalLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") - } - } + @Test + fun `Submitting provide this later on licensing routes to unoccupied provide licensing later page`(page: Page) { + featureFlagManager.enableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + + val taskListPage = + navigator.goToRestructuredPropertyRegistrationTaskList( + PropertyStateSessionBuilder + .beforePropertyRegistrationOwnershipType() + .withBedrooms() + .withOwnershipType() + .withHasNoJointLandlords() + .withOccupancyStatus(false), + ) + taskListPage.clickRentedOutTaskWithName("Tell us if your property needs a license") + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + assertThat(licensingTypePage.provideThisLaterButton).isVisible() + + licensingTypePage.submitProvideThisLater() + val provideLicensingLaterPage = assertPageIs(page, ProvideLicensingLaterFormPagePropertyRegistration::class) - @Nested - inner class OccupancyStep { - @Test - fun `Submitting with no occupancy option selected returns an error`(page: Page) { - val occupancyPage = navigator.skipToPropertyRegistrationOccupancyPage() - occupancyPage.form.submit() - assertThat(occupancyPage.form.getErrorMessage()).containsText("Select whether the property is occupied") + BaseComponent + .assertThat(provideLicensingLaterPage.heading) + .containsText("Provide details about property licensing later") + BaseComponent.assertThat(provideLicensingLaterPage.insetText).isHidden() + } } - } - @Nested - inner class NumberOfHouseholdsStep { - @Test - fun `Submitting with a blank numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() - householdsPage.form.submit() - assertThat(householdsPage.form.getErrorMessage()).containsText("Enter how many separate households, like 1 or 2") - } + @Nested + inner class SelectiveLicenceStep { + @Test + fun `Submitting with no licence number returns an error`(page: Page) { + val selectiveLicencePage = navigator.skipToPropertyRegistrationOccupiedSelectiveLicencePage() + selectiveLicencePage.form.submit() + assertThat(selectiveLicencePage.form.getErrorMessage()).containsText("Enter the selective licence number") + } - @Test - fun `Submitting with a non-numerical value in the numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() - householdsPage.submitNumberOfHouseholds("not-a-number") - assertThat(householdsPage.form.getErrorMessage()) - .containsText("Enter how many separate households, like 1 or 2") + @Test + fun `Submitting with a very long licence number returns an error`(page: Page) { + val selectiveLicencePage = navigator.skipToPropertyRegistrationOccupiedSelectiveLicencePage() + val aVeryLongString = + "This string is very long, so long that it is not feasible that it is a real licence number " + + "- therefore if it is submitted there will in fact be an error rather than a successful submission." + + " It is actually quite difficult for a string to be long enough to trigger this error, because the" + + " maximum length has been selected to be permissive of id numbers we do not expect while still having " + + "a cap reachable with a little effort." + selectiveLicencePage.submitLicenseNumber(aVeryLongString) + assertThat(selectiveLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") + } } - @Test - fun `Submitting with a non-integer number in the numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() - householdsPage.submitNumberOfHouseholds("2.3") - assertThat(householdsPage.form.getErrorMessage()) - .containsText("Enter how many separate households, like 1 or 2") - } + @Nested + inner class HmoMandatoryLicenceStep { + @Test + fun `Submitting with a licence number redirects to the next step`(page: Page) { + val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationOccupiedHmoMandatoryLicencePage() + hmoMandatoryLicencePage.submitLicenseNumber("licence number") + assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + } - @Test - fun `Submitting with a negative integer in the numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() - householdsPage.submitNumberOfHouseholds(-2) - assertThat(householdsPage.form.getErrorMessage()) - .containsText("Enter how many separate households, like 1 or 2") - } + @Test + fun `Submitting with no licence number returns an error`(page: Page) { + val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationOccupiedHmoMandatoryLicencePage() + hmoMandatoryLicencePage.form.submit() + assertThat(hmoMandatoryLicencePage.form.getErrorMessage()).containsText("Enter the HMO Mandatory licence number") + } - @Test - fun `Submitting with a zero integer in the numberOfHouseholds field returns an error`(page: Page) { - val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() - householdsPage.submitNumberOfHouseholds(0) - assertThat(householdsPage.form.getErrorMessage()) - .containsText("Enter how many separate households, like 1 or 2") + @Test + fun `Submitting with a very long licence number returns an error`(page: Page) { + val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationOccupiedHmoMandatoryLicencePage() + val aVeryLongString = + "This string is very long, so long that it is not feasible that it is a real licence number " + + "- therefore if it is submitted there will in fact be an error rather than a successful submission." + + " It is actually quite difficult for a string to be long enough to trigger this error, because the" + + " maximum length has been selected to be permissive of id numbers we do not expect while still having " + + "a cap reachable with a little effort." + hmoMandatoryLicencePage.submitLicenseNumber(aVeryLongString) + assertThat(hmoMandatoryLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") + } } - } - @Nested - inner class NumberOfPeopleStep { - @Test - fun `Submitting with a blank numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() - peoplePage.form.submit() - assertThat(peoplePage.form.getErrorMessage()).containsText("Enter how many people, like 2 or 5") - } - - @Test - fun `Submitting with a non-numerical value in the numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() - peoplePage.submitNumOfPeople("not-a-number") - assertThat(peoplePage.form.getErrorMessage()) - .containsText("Enter how many people, like 2 or 5") - } - - @Test - fun `Submitting with a non-integer number in the numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() - peoplePage.submitNumOfPeople("2.3") - assertThat(peoplePage.form.getErrorMessage()) - .containsText("Enter how many people, like 2 or 5") - } - - @Test - fun `Submitting with a negative integer in the numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() - peoplePage.submitNumOfPeople("-2") - assertThat(peoplePage.form.getErrorMessage()) - .containsText("Enter how many people, like 2 or 5") - } - - @Test - fun `Submitting with a zero integer in the numberOfPeople field returns an error`(page: Page) { - val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() - peoplePage.submitNumOfPeople(0) - assertThat(peoplePage.form.getErrorMessage()) - .containsText("Enter how many people, like 2 or 5") - } - - @Test - fun `Submitting with an integer in the numberOfPeople field that is less than the numberOfHouseholds returns an error`( - page: Page, - ) { - val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() - householdsPage.submitNumberOfHouseholds(3) - val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) - peoplePage.submitNumOfPeople(2) - assertThat(peoplePage.form.getErrorMessage()) - .containsText( - "The number of people in the property must be the same as or higher than the number of households in the property", - ) - } - } + @Nested + inner class HmoAdditionalLicenceStep { + @Test + fun `Submitting with a licence number redirects to the next step`(page: Page) { + val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationOccupiedHmoAdditionalLicencePage() + hmoAdditionalLicencePage.submitLicenseNumber("licence number") + assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + } - @Nested - inner class NumberOfBedroomsStep { - val numberOfBedroomsErrorMessage = "Enter the number of bedrooms, like 3 or 8" + @Test + fun `Submitting with no licence number returns an error`(page: Page) { + val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationOccupiedHmoAdditionalLicencePage() + hmoAdditionalLicencePage.form.submit() + assertThat(hmoAdditionalLicencePage.form.getErrorMessage()).containsText("Enter the HMO additional licence number") + } - @Test - fun `Submitting with a blank numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.form.submit() - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) + @Test + fun `Submitting with a very long licence number returns an error`(page: Page) { + val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationOccupiedHmoAdditionalLicencePage() + val aVeryLongString = + "This string is very long, so long that it is not feasible that it is a real licence number " + + "- therefore if it is submitted there will in fact be an error rather than a successful submission." + + " It is actually quite difficult for a string to be long enough to trigger this error, because the" + + " maximum length has been selected to be permissive of id numbers we do not expect while still having " + + "a cap reachable with a little effort." + hmoAdditionalLicencePage.submitLicenseNumber(aVeryLongString) + assertThat(hmoAdditionalLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") + } } - @Test - fun `Submitting with a non-numerical value in the numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.submitNumOfBedrooms("not-a-number") - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) + @Nested + inner class OccupancyStep { + @Test + fun `Submitting with no occupancy option selected returns an error`(page: Page) { + val occupancyPage = navigator.skipToPropertyRegistrationRestructuredOccupancyPage() + occupancyPage.form.submit() + assertThat(occupancyPage.form.getErrorMessage()).containsText("Select whether the property is occupied") + } } - @Test - fun `Submitting with a non-integer number in the numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.submitNumOfBedrooms("2.3") - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } + @Nested + inner class NumberOfHouseholdsStep { + @Test + fun `Submitting with a blank numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToTenancyDetailsHouseholdsPage() + householdsPage.form.submit() + assertThat(householdsPage.form.getErrorMessage()).containsText("Enter how many separate households, like 1 or 2") + } - @Test - fun `Submitting with a negative integer in the numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.submitNumOfBedrooms("-2") - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } + @Test + fun `Submitting with a non-numerical value in the numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToTenancyDetailsHouseholdsPage() + householdsPage.submitNumberOfHouseholds("not-a-number") + assertThat(householdsPage.form.getErrorMessage()) + .containsText("Enter how many separate households, like 1 or 2") + } - @Test - fun `Submitting with a zero integer in the numberOfBedrooms field returns an error`(page: Page) { - val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() - bedroomsPage.submitNumOfBedrooms(0) - assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) - } - } + @Test + fun `Submitting with a non-integer number in the numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToTenancyDetailsHouseholdsPage() + householdsPage.submitNumberOfHouseholds("2.3") + assertThat(householdsPage.form.getErrorMessage()) + .containsText("Enter how many separate households, like 1 or 2") + } - @Nested - inner class RentIncludesBillsStep { - @Test - fun `Submitting with no rent included option selected returns an error`(page: Page) { - val rentIncludesBillsPage = navigator.skipToPropertyRegistrationRentIncludesBillsPage() - rentIncludesBillsPage.form.submit() - assertThat(rentIncludesBillsPage.form.getErrorMessage()).containsText("Select whether the rent includes bills") - } - } + @Test + fun `Submitting with a negative integer in the numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToTenancyDetailsHouseholdsPage() + householdsPage.submitNumberOfHouseholds(-2) + assertThat(householdsPage.form.getErrorMessage()) + .containsText("Enter how many separate households, like 1 or 2") + } - @Nested - inner class BillsIncludedStep { - @Test - fun `Submitting with no bills included selected returns an error`(page: Page) { - val billsIncludedPage = navigator.skipToPropertyRegistrationBillsIncludedPage() - billsIncludedPage.form.submit() - assertThat(billsIncludedPage.form.getErrorMessage()).containsText("Select what you include in the rent") - } - - @Test - fun `Submitting with something else selected but no text entered returns an error`(page: Page) { - val billsIncludedPage = navigator.skipToPropertyRegistrationBillsIncludedPage() - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.selectSomethingElseCheckbox() - billsIncludedPage.form.submit() - assertThat(billsIncludedPage.form.getErrorMessage()).containsText("Enter the bills and services you include in the rent") - } - - @Test - fun `Submitting with a very long something else text returns an error`(page: Page) { - val billsIncludedPage = navigator.skipToPropertyRegistrationBillsIncludedPage() - billsIncludedPage.selectGasElectricityWater() - billsIncludedPage.selectSomethingElseCheckbox() - val aVeryLongString = - "This string is very long, so long that it is not feasible that it is a real description " + - "- therefore if it is submitted there will in fact be an error rather than a successful submission." + - " It is actually quite difficult for a string to be long enough to trigger this error, because the" + - " maximum length has been selected to be permissive of descriptions we do not expect while still having " + - "a cap reachable with a little effort." - billsIncludedPage.fillCustomBills(aVeryLongString) - billsIncludedPage.form.submit() - assertThat(billsIncludedPage.form.getErrorMessage("customBillsIncluded")) - .containsText("The description of other bills and services must be 200 characters or fewer") + @Test + fun `Submitting with a zero integer in the numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToTenancyDetailsHouseholdsPage() + householdsPage.submitNumberOfHouseholds(0) + assertThat(householdsPage.form.getErrorMessage()) + .containsText("Enter how many separate households, like 1 or 2") + } } - } - @Nested - inner class FurnishedStatusStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val furnishedStatusPage = navigator.skipToPropertyRegistrationFurnishedStatusPage() - furnishedStatusPage.form.submit() - assertThat( - furnishedStatusPage.form.getErrorMessage(), - ).containsText("Select whether the property is furnished, partly furnished or unfurnished") - } - } + @Nested + inner class NumberOfPeopleStep { + @Test + fun `Submitting with a blank numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToTenancyDetailsPeoplePage() + peoplePage.form.submit() + assertThat(peoplePage.form.getErrorMessage()).containsText("Enter how many people, like 2 or 5") + } - @Nested - inner class RentFrequencyStep { - @Test - fun `Submitting with no rentFrequency selected returns an error`(page: Page) { - val rentFrequencyPage = navigator.skipToPropertyRegistrationRentFrequencyPage() - rentFrequencyPage.form.submit() - assertThat(rentFrequencyPage.form.getErrorMessage()).containsText("Select how often you charge rent") - } + @Test + fun `Submitting with a non-numerical value in the numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToTenancyDetailsPeoplePage() + peoplePage.submitNumOfPeople("not-a-number") + assertThat(peoplePage.form.getErrorMessage()) + .containsText("Enter how many people, like 2 or 5") + } - @Test - fun `Submitting with other rent frequency selected but no text entered returns an error`(page: Page) { - val rentFrequencyPage = navigator.skipToPropertyRegistrationRentFrequencyPage() - rentFrequencyPage.selectRentFrequency(RentFrequency.OTHER) - rentFrequencyPage.form.submit() - assertThat(rentFrequencyPage.form.getErrorMessage()).containsText("Enter how often you charge rent") - } - } + @Test + fun `Submitting with a non-integer number in the numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToTenancyDetailsPeoplePage() + peoplePage.submitNumOfPeople("2.3") + assertThat(peoplePage.form.getErrorMessage()) + .containsText("Enter how many people, like 2 or 5") + } - @Nested - inner class RentAmountStep { - @Test - fun `Submitting no rentAmount returns an error`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() - rentAmountPage.form.submit() - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") - } + @Test + fun `Submitting with a negative integer in the numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToTenancyDetailsPeoplePage() + peoplePage.submitNumOfPeople("-2") + assertThat(peoplePage.form.getErrorMessage()) + .containsText("Enter how many people, like 2 or 5") + } - @Test - fun `Submitting a rentAmount greater than two decimals returns an error`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() - rentAmountPage.submitRentAmount("400.123") - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") - } + @Test + fun `Submitting with a zero integer in the numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToTenancyDetailsPeoplePage() + peoplePage.submitNumOfPeople(0) + assertThat(peoplePage.form.getErrorMessage()) + .containsText("Enter how many people, like 2 or 5") + } - @Test - fun `Submitting a negative rentAmount returns an error`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() - rentAmountPage.submitRentAmount("-400.12") - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + @Test + fun `Submitting with an integer in the numberOfPeople field that is less than the numberOfHouseholds returns an error`( + page: Page, + ) { + val householdsPage = navigator.skipToTenancyDetailsHouseholdsPage() + householdsPage.submitNumberOfHouseholds(3) + val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) + peoplePage.submitNumOfPeople(2) + assertThat(peoplePage.form.getErrorMessage()) + .containsText( + "The number of people in the property must be the same as or higher than the number of households in the property", + ) + } } - @Test - fun `Submitting a non-numerical rentAmount returns an error`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() - rentAmountPage.submitRentAmount("not-a-number") - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") - } + @Nested + inner class NumberOfBedroomsStep { + val numberOfBedroomsErrorMessage = "Enter the number of bedrooms, like 3 or 8" - @Test - fun `Submitting a rentAmount of 10000000 or above returns an error`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() - rentAmountPage.submitRentAmount("10000000") - assertThat( - rentAmountPage.form.getErrorMessage(), - ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") - } + @Test + fun `Submitting with a blank numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.form.submit() + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) + } - @Nested - inner class ConditionalContentPerRentFrequency { @Test - fun `Page renders correctly for weekly rent frequency`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.WEEKLY) - BaseComponent - .assertThat(rentAmountPage.header) - .containsText("What is the weekly rent?") - BaseComponent - .assertThat(rentAmountPage.subheading) - .containsText("Weekly rent") - BaseComponent - .assertThat(rentAmountPage.billsExplanationForRentFrequency) - .containsText("The amount you enter must be the total weekly rent agreed with the tenant.") - BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() + fun `Submitting with a non-numerical value in the numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.submitNumOfBedrooms("not-a-number") + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) } @Test - fun `Page renders correctly for four weekly rent frequency`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.FOUR_WEEKLY) - BaseComponent - .assertThat(rentAmountPage.header) - .containsText("What is the 4-weekly rent?") - BaseComponent - .assertThat(rentAmountPage.subheading) - .containsText("4-weekly rent") - BaseComponent - .assertThat(rentAmountPage.billsExplanationForRentFrequency) - .containsText("The amount you enter must be the total 4-weekly rent agreed with the tenant.") - BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() + fun `Submitting with a non-integer number in the numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.submitNumOfBedrooms("2.3") + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) } @Test - fun `Page renders correctly for monthly rent frequency`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.MONTHLY) - BaseComponent - .assertThat(rentAmountPage.header) - .containsText("What is the monthly rent?") - BaseComponent - .assertThat(rentAmountPage.subheading) - .containsText("Monthly rent") - BaseComponent - .assertThat(rentAmountPage.billsExplanationForRentFrequency) - .containsText("The amount you enter must be the total monthly rent agreed with the tenant.") - BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() + fun `Submitting with a negative integer in the numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.submitNumOfBedrooms("-2") + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) } @Test - fun `Page renders correctly for 'other' rent frequency`(page: Page) { - val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.OTHER) - BaseComponent - .assertThat(rentAmountPage.header) - .containsText("What is the monthly rent?") - BaseComponent - .assertThat(rentAmountPage.subheading) - .containsText("Monthly rent") - BaseComponent - .assertThat(rentAmountPage.billsExplanationForRentFrequency) - .containsText("The amount you enter must be the total monthly rent agreed with the tenant.") - BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isVisible() + fun `Submitting with a zero integer in the numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.submitNumOfBedrooms(0) + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) } } - } - @Nested - inner class HasJointLandlordsStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val hasJointLandlordsPage = navigator.skipToPropertyRegistrationHasJointLandlordsPage() - hasJointLandlordsPage.form.submit() - assertThat(hasJointLandlordsPage.form.getErrorMessage()) - .containsText("Select if there are any other landlords for this property") - } - - @Test - fun `The link renders correctly`(page: Page) { - val hasJointLandlordsPage = navigator.skipToPropertyRegistrationHasJointLandlordsPage() - BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("href", GOV_LEGAL_ADVICE_URL) - BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("rel", "noreferrer noopener") - BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("target", "_blank") + @Nested + inner class RentIncludesBillsStep { + @Test + fun `Submitting with no rent included option selected returns an error`(page: Page) { + val rentIncludesBillsPage = navigator.skipToTenancyDetailsRentIncludesBillsPage() + rentIncludesBillsPage.form.submit() + assertThat(rentIncludesBillsPage.form.getErrorMessage()).containsText("Select whether the rent includes bills") + } } - } - @Nested - inner class ManagingJointLandlords { - @Test - fun `Submitting remove a joint landlord with no option selected returns an error`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") + @Nested + inner class BillsIncludedStep { + @Test + fun `Submitting with no bills included selected returns an error`() { + val billsIncludedPage = navigator.skipToTenancyDetailsBillsIncludedPage() + billsIncludedPage.form.submit() + assertThat(billsIncludedPage.form.getErrorMessage()).containsText("Select what you include in the rent") + } - val checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + @Test + fun `Submitting with something else selected but no text entered returns an error`() { + val billsIncludedPage = navigator.skipToTenancyDetailsBillsIncludedPage() + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.selectSomethingElseCheckbox() + billsIncludedPage.form.submit() + assertThat(billsIncludedPage.form.getErrorMessage()).containsText("Enter the bills and services you include in the rent") + } - val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.form.submit() - assertThat(removeJointLandlordPage.form.getErrorMessage()) - .containsText("Select if you want to remove this joint landlord") + @Test + fun `Submitting with a very long something else text returns an error`() { + val billsIncludedPage = navigator.skipToTenancyDetailsBillsIncludedPage() + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.selectSomethingElseCheckbox() + val aVeryLongString = + "This string is very long, so long that it is not feasible that it is a real description " + + "- therefore if it is submitted there will in fact be an error rather than a successful submission." + + " It is actually quite difficult for a string to be long enough to trigger this error, because the" + + " maximum length has been selected to be permissive of descriptions we do not expect while still having " + + "a cap reachable with a little effort." + billsIncludedPage.fillCustomBills(aVeryLongString) + billsIncludedPage.form.submit() + assertThat(billsIncludedPage.form.getErrorMessage("customBillsIncluded")) + .containsText("The description of other bills and services must be 200 characters or fewer") + } } - @Test - fun `Submitting remove a joint landlord with No selected returns to the check page without removing the landlord`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") - - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + @Nested + inner class FurnishedStatusStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val furnishedStatusPage = navigator.skipToTenancyDetailsFurnishedStatusPage() + furnishedStatusPage.form.submit() + assertThat( + furnishedStatusPage.form.getErrorMessage(), + ).containsText("Select whether the property is furnished, partly furnished or unfurnished") + } + } - val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.submitDoesNotWantToProceed() + @Nested + inner class RentFrequencyStep { + @Test + fun `Submitting with no rentFrequency selected returns an error`() { + val rentFrequencyPage = navigator.skipToTenancyDetailsRentFrequencyPage() + rentFrequencyPage.form.submit() + assertThat(rentFrequencyPage.form.getErrorMessage()).containsText("Select how often you charge rent") + } - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + @Test + fun `Submitting with other rent frequency selected but no text entered returns an error`() { + val rentFrequencyPage = navigator.skipToTenancyDetailsRentFrequencyPage() + rentFrequencyPage.selectRentFrequency(RentFrequency.OTHER) + rentFrequencyPage.form.submit() + assertThat(rentFrequencyPage.form.getErrorMessage()).containsText("Enter how often you charge rent") + } } - @Test - fun `Clicking cancel returns to the check page regardless of selected remove answer`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") + @Nested + inner class RentAmountStep { + @Test + fun `Submitting no rentAmount returns an error`(page: Page) { + val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage() + rentAmountPage.form.submit() + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + } - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.form.addAnotherButton.clickAndWait() + @Test + fun `Submitting a rentAmount greater than two decimals returns an error`(page: Page) { + val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage() + rentAmountPage.submitRentAmount("400.123") + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + } - val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - inviteAnotherJointLandlordPage.submitEmail("beta@example.com") + @Test + fun `Submitting a negative rentAmount returns an error`(page: Page) { + val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage() + rentAmountPage.submitRentAmount("-400.12") + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + } - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + @Test + fun `Submitting a non-numerical rentAmount returns an error`(page: Page) { + val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage() + rentAmountPage.submitRentAmount("not-a-number") + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + } - var removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.form.areYouSureRadios.selectValue("true") - removeJointLandlordPage.cancelLink.clickAndWait() + @Test + fun `Submitting a rentAmount of 10000000 or above returns an error`(page: Page) { + val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage() + rentAmountPage.submitRentAmount("10000000") + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + } - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + @Nested + inner class ConditionalContentPerRentFrequency { + @Test + fun `Page renders correctly for weekly rent frequency`(page: Page) { + val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage(RentFrequency.WEEKLY) + BaseComponent + .assertThat(rentAmountPage.header) + .containsText("What is the weekly rent?") + BaseComponent + .assertThat(rentAmountPage.subheading) + .containsText("Weekly rent") + BaseComponent + .assertThat(rentAmountPage.billsExplanationForRentFrequency) + .containsText("The amount you enter must be the total weekly rent agreed with the tenant.") + BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() + } + + @Test + fun `Page renders correctly for four weekly rent frequency`(page: Page) { + val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage(RentFrequency.FOUR_WEEKLY) + BaseComponent + .assertThat(rentAmountPage.header) + .containsText("What is the 4-weekly rent?") + BaseComponent + .assertThat(rentAmountPage.subheading) + .containsText("4-weekly rent") + BaseComponent + .assertThat(rentAmountPage.billsExplanationForRentFrequency) + .containsText("The amount you enter must be the total 4-weekly rent agreed with the tenant.") + BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() + } + + @Test + fun `Page renders correctly for monthly rent frequency`(page: Page) { + val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage(RentFrequency.MONTHLY) + BaseComponent + .assertThat(rentAmountPage.header) + .containsText("What is the monthly rent?") + BaseComponent + .assertThat(rentAmountPage.subheading) + .containsText("Monthly rent") + BaseComponent + .assertThat(rentAmountPage.billsExplanationForRentFrequency) + .containsText("The amount you enter must be the total monthly rent agreed with the tenant.") + BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() + } + + @Test + fun `Page renders correctly for 'other' rent frequency`(page: Page) { + val rentAmountPage = navigator.skipToTenancyDetailsRentAmountPage(RentFrequency.OTHER) + BaseComponent + .assertThat(rentAmountPage.header) + .containsText("What is the monthly rent?") + BaseComponent + .assertThat(rentAmountPage.subheading) + .containsText("Monthly rent") + BaseComponent + .assertThat(rentAmountPage.billsExplanationForRentFrequency) + .containsText("The amount you enter must be the total monthly rent agreed with the tenant.") + BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isVisible() + } + } + } - removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.form.areYouSureRadios.selectValue("false") - removeJointLandlordPage.cancelLink.clickAndWait() + @Nested + inner class HasJointLandlordsStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val hasJointLandlordsPage = navigator.skipToPropertyRegistrationHasJointLandlordsPage() + hasJointLandlordsPage.form.submit() + assertThat(hasJointLandlordsPage.form.getErrorMessage()) + .containsText("Select if there are any other landlords for this property") + } - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") + @Test + fun `The link renders correctly`(page: Page) { + val hasJointLandlordsPage = navigator.skipToPropertyRegistrationHasJointLandlordsPage() + BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("href", GOV_LEGAL_ADVICE_URL) + BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("rel", "noreferrer noopener") + BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("target", "_blank") + } } - @Test - fun `Removing joint landlords works as expected`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") + @Nested + inner class ManagingJointLandlords { + @Test + fun `Submitting remove a joint landlord with no option selected returns an error`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.form.addAnotherButton.clickAndWait() + val checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - inviteAnotherJointLandlordPage.submitEmail("beta@example.com") + val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.form.submit() + assertThat(removeJointLandlordPage.form.getErrorMessage()) + .containsText("Select if you want to remove this joint landlord") + } - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + @Test + fun `Submitting remove a joint landlord with No selected returns to the check page without removing the landlord`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") - var removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.submitWantsToProceed() + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("beta@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.submitDoesNotWantToProceed() - removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.submitWantsToProceed() + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + } - assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) - } + @Test + fun `Clicking cancel returns to the check page regardless of selected remove answer`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") - @Test - fun `Editing joint landlords works as expected`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.form.addAnotherButton.clickAndWait() - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.form.addAnotherButton.clickAndWait() + val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + inviteAnotherJointLandlordPage.submitEmail("beta@example.com") - var inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - inviteAnotherJointLandlordPage.submitEmail("beta@example.com") + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Change") + var removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.form.areYouSureRadios.selectValue("true") + removeJointLandlordPage.cancelLink.clickAndWait() - inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - BaseComponent.assertThat(inviteAnotherJointLandlordPage.form.emailInput).hasValue("alpha@example.com") - inviteAnotherJointLandlordPage.submitEmail("gamma@example.com") + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("gamma@example.com") - } + removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.form.areYouSureRadios.selectValue("false") + removeJointLandlordPage.cancelLink.clickAndWait() - @Test - fun `Numbering on page and tables is correct`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("alpha@example.com") + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") + } - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") - assertThat(checkJointLandlordPage.summaryList.firstRow.key).containsText("Joint landlord 1") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") - checkJointLandlordPage.form.addAnotherButton.clickAndWait() + @Test + fun `Removing joint landlords works as expected`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") - val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - inviteAnotherJointLandlordPage.submitEmail("beta@example.com") + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.form.addAnotherButton.clickAndWait() - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") - assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).key).containsText("Joint landlord 2") - assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + inviteAnotherJointLandlordPage.submitEmail("beta@example.com") - val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) - removeJointLandlordPage.submitWantsToProceed() + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") - assertThat(checkJointLandlordPage.summaryList.firstRow.key).containsText("Joint landlord 1") - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("beta@example.com") - } - } + var removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.submitWantsToProceed() - @Nested - inner class InviteJointLandlordsStep { - @Test - fun `Submitting with no email returns an error`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("") - assertThat(inviteJointLandlordsPage.form.getErrorMessage()) - .containsText("Enter an email address in the correct format, like name@example.com") - } - - @Test - fun `Submitting with an invalid email returns an error`(page: Page) { - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail("not-an-email") - assertThat(inviteJointLandlordsPage.form.getErrorMessage()) - .containsText("Enter an email address in the correct format, like name@example.com") - } - } + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("beta@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") - @Nested - inner class InviteAnotherJointLandlordsStep { - @Test - fun `Submitting with an already invited email returns an error`(page: Page) { - val alreadyInvitedEmail = "already@invited.com" - val inviteJointLandlordsPage = - navigator.skipToPropertyRegistrationInviteAnotherJointLandlordPage(mutableListOf(alreadyInvitedEmail)) - inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) - assertThat(inviteJointLandlordsPage.form.getErrorMessage()) - .containsText("You have already invited this email address") - } + removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.submitWantsToProceed() - @Test - fun `Submitting with an invited email in edit mode is permitted`(page: Page) { - val alreadyInvitedEmail = "already@invited.com" + assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + } - val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() - inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) + @Test + fun `Editing joint landlords works as expected`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") - var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Change") + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.form.addAnotherButton.clickAndWait() - val editJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) - BaseComponent.assertThat(editJointLandlordPage.form.emailInput).hasValue(alreadyInvitedEmail) - inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) + var inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + inviteAnotherJointLandlordPage.submitEmail("beta@example.com") - checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) - assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText(alreadyInvitedEmail) - } - } + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Change") - @Nested - inner class HasGasSupplyStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage() - hasGasSupplyPage.form.submit() - assertThat(hasGasSupplyPage.form.getErrorMessage()).containsText("Select whether you have a gas supply or any gas appliances") - } + inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + BaseComponent.assertThat(inviteAnotherJointLandlordPage.form.emailInput).hasValue("alpha@example.com") + inviteAnotherJointLandlordPage.submitEmail("gamma@example.com") - @Test - fun `Submitting No navigates to the check you gas answers step`(page: Page) { - val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage() - hasGasSupplyPage.submitHasNoGasSupply() - assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) - } - } + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("gamma@example.com") + } - @Nested - inner class HasGasSafetyCertStep { - @Test - fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { - val hasGasSafetyCertPage = navigator.skipToPropertyRegistrationHasGasCertPage() - hasGasSafetyCertPage.form.submitPrimaryButton() - assertThat( - hasGasSafetyCertPage.form.getErrorMessage(), - ).containsText("Select whether you have a gas safety certificate") + @Test + fun `Numbering on page and tables is correct`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") + + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") + assertThat(checkJointLandlordPage.summaryList.firstRow.key).containsText("Joint landlord 1") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + checkJointLandlordPage.form.addAnotherButton.clickAndWait() + + val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + inviteAnotherJointLandlordPage.submitEmail("beta@example.com") + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") + assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).key).containsText("Joint landlord 2") + assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + + val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.submitWantsToProceed() + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") + assertThat(checkJointLandlordPage.summaryList.firstRow.key).containsText("Joint landlord 1") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("beta@example.com") + } } - } - @Nested - inner class GasSafetyIssueDateStepTests { - @ParameterizedTest(name = "{0}") - @Suppress("ktlint:standard:max-line-length") - @MethodSource( - "uk.gov.communities.prsdb.webapp.testHelpers.parameterProviders.TodayOrPastDateValidationTestParameterProvider#provideInvalidDateStrings", - ) - fun `Submitting returns a corresponding error when`( - dayMonthYear: Triple, - expectedErrorMessage: String, - ) { - val (day, month, year) = dayMonthYear - val gasSafetyIssueDatePage = navigator.skipToPropertyRegistrationGasCertIssueDatePage() - gasSafetyIssueDatePage.submitDate(day, month, year) - assertThat(gasSafetyIssueDatePage.form.getErrorMessage()).containsText(expectedErrorMessage) + @Nested + inner class InviteJointLandlordsStep { + @Test + fun `Submitting with no email returns an error`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("") + assertThat(inviteJointLandlordsPage.form.getErrorMessage()) + .containsText("Enter an email address in the correct format, like name@example.com") + } + + @Test + fun `Submitting with an invalid email returns an error`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("not-an-email") + assertThat(inviteJointLandlordsPage.form.getErrorMessage()) + .containsText("Enter an email address in the correct format, like name@example.com") + } } - } - @Nested - inner class CheckGasSafetyAnswersStep { - @Test - fun `No gas supply - gas supply change link navigates to has gas supply page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersNoGasSupply(), + @Nested + inner class InviteAnotherJointLandlordsStep { + @Test + fun `Submitting with an already invited email returns an error`(page: Page) { + val alreadyInvitedEmail = "already@invited.com" + val inviteJointLandlordsPage = + navigator.skipToPropertyRegistrationInviteAnotherJointLandlordPage(mutableListOf(alreadyInvitedEmail)) + inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) + assertThat(inviteJointLandlordsPage.form.getErrorMessage()) + .containsText("You have already invited this email address") + } + + @Test + fun `Submitting with an invited email in edit mode is permitted`(page: Page) { + val alreadyInvitedEmail = "already@invited.com" + + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) + + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Change") + + val editJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + BaseComponent.assertThat(editJointLandlordPage.form.emailInput).hasValue(alreadyInvitedEmail) + inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText(alreadyInvitedEmail) + } + } + + @Nested + inner class HasGasSupplyStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage() + hasGasSupplyPage.form.submit() + assertThat( + hasGasSupplyPage.form.getErrorMessage(), + ).containsText("Select whether you have a gas supply or any gas appliances") + } + + @Test + fun `Submitting No navigates to the check you gas answers step`(page: Page) { + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage() + hasGasSupplyPage.submitHasNoGasSupply() + assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + } + } + + @Nested + inner class HasGasSafetyCertStep { + @Test + fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { + val hasGasSafetyCertPage = navigator.skipToPropertyRegistrationHasGasCertPage() + hasGasSafetyCertPage.form.submitPrimaryButton() + assertThat( + hasGasSafetyCertPage.form.getErrorMessage(), + ).containsText("Select whether you have a gas safety certificate") + } + } + + @Nested + inner class GasSafetyIssueDateStepTests { + @ParameterizedTest(name = "{0}") + @Suppress("ktlint:standard:max-line-length") + @MethodSource( + "uk.gov.communities.prsdb.webapp.testHelpers.parameterProviders.TodayOrPastDateValidationTestParameterProvider#provideInvalidDateStrings", + ) + fun `Submitting returns a corresponding error when`( + dayMonthYear: Triple, + expectedErrorMessage: String, + ) { + val (day, month, year) = dayMonthYear + val gasSafetyIssueDatePage = navigator.skipToPropertyRegistrationGasCertIssueDatePage() + gasSafetyIssueDatePage.submitDate(day, month, year) + assertThat(gasSafetyIssueDatePage.form.getErrorMessage()).containsText(expectedErrorMessage) + } + } + + @Nested + inner class CheckGasSafetyAnswersStep { + @Test + fun `No gas supply - gas supply change link navigates to has gas supply page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersNoGasSupply(), + ) + cyaPage.gasSupplySummaryList.gasSupplyRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + } + + @Test + fun `Uploaded cert - gas supply change link navigates to has gas supply page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), + ) + cyaPage.gasSupplySummaryList.gasSupplyRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + } + + @Test + fun `Uploaded cert - valid gas cert change link navigates to has gas cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), + ) + cyaPage.certSummaryList.validGasCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + } + + @Test + fun `Uploaded cert - issue date change link navigates to issue date page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), + ) + cyaPage.certSummaryList.issueDateRow.clickFirstActionLinkAndWait() + assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + } + + @Test + fun `Uploaded cert - certificate change link navigates to check uploads page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), + ) + cyaPage.certSummaryList.yourCertificateRow.clickFirstActionLinkAndWait() + assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) + } + + @Test + fun `Provide later - gas cert change link navigates to has gas cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersProvideLater(), + ) + cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + } + + @Test + fun `No cert - gas cert change link navigates to has gas cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersNoCert(), + ) + cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + } + + @Test + fun `Cert expired - gas cert change link navigates to has gas cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersCertExpired(), + ) + cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + } + } + + @Nested + inner class HasElectricalCertStep { + @Test + fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { + val hasElectricalCertPage = navigator.skipToPropertyRegistrationHasElectricalCertPage() + hasElectricalCertPage.form.submitPrimaryButton() + assertThat( + hasElectricalCertPage.form.getErrorMessage(), + ).containsText("Select which electrical safety certificate you have") + } + } + + @Nested + inner class CheckElectricalSafetyAnswersStep { + @Test + fun `Cert uploaded EIC - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } + + @Test + fun `Cert uploaded EIC - expiry date change link navigates to expiry date page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), + ) + cyaPage.summaryList.expiryDateRow.clickFirstActionLinkAndWait() + assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + } + + @Test + fun `Cert uploaded EIC - certificate change link navigates to check uploads page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), + ) + cyaPage.summaryList.yourCertificateRow.clickFirstActionLinkAndWait() + assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + } + + @Test + fun `Cert uploaded EICR - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEicr(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } + + @Test + fun `Provide later - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersProvideLater(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } + + @Test + fun `No cert - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersNoCert(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } + + @Test + fun `Cert expired - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersCertExpired(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } + } + + @Nested + inner class ElectricalCertExpiryDateStepTests { + @ParameterizedTest(name = "{0}") + @Suppress("ktlint:standard:max-line-length") + @MethodSource( + "uk.gov.communities.prsdb.webapp.testHelpers.parameterProviders.AnyDateValidationTestParameterProvider#provideInvalidDateStrings", + ) + fun `Submitting returns a corresponding error when`( + dayMonthYear: Triple, + expectedErrorMessage: String, + ) { + val (day, month, year) = dayMonthYear + val electricalCertExpiryDatePage = navigator.skipToPropertyRegistrationElectricalCertExpiryDatePage() + electricalCertExpiryDatePage.submitDate(day, month, year) + assertThat(electricalCertExpiryDatePage.form.getErrorMessage()).containsText(expectedErrorMessage) + } + } + + @Nested + inner class HasEpcStepTests { + @Test + fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { + val hasEpcPage = navigator.skipToPropertyRegistrationHasEpcPage() + hasEpcPage.form.submitPrimaryButton() + assertThat(hasEpcPage.form.getErrorMessage()) + .containsText("Select if you have an EPC for this property") + } + } + + @Nested + inner class FindYourEpcStepTests { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() + findYourEpcPage.form.submit() + assertThat(findYourEpcPage.form.getErrorMessage()) + .containsText("Enter a certificate number") + } + } + + @Nested + inner class ConfirmEpcDetailsRetrievedByCertificateNumberStepTests { + @Test + fun `User sees a validation error when they do not select an answer`(page: Page) { + val confirmEpcDetailsPage = + navigator.skipToPropertyRegistrationConfirmEpcDetailsRetrievedByCertificateNumberPage() + confirmEpcDetailsPage.form.submit() + assertThat(confirmEpcDetailsPage.form.getErrorMessage()) + .containsText("Select if you want to use this EPC") + } + } + + @Nested + inner class IsEpcRequiredStepTests { + @Test + fun `Submitting with no option selected returns a validation error`(page: Page) { + val isEpcRequiredPage = navigator.skipToPropertyRegistrationIsEpcRequiredPage() + isEpcRequiredPage.form.submit() + assertThat(isEpcRequiredPage.form.getErrorMessage()) + .containsText("Select if an EPC is required to let this property") + } + } + + @Nested + inner class ConfirmEpcDetailsByUprnStepTests { + @Test + fun `User sees a validation error when they do not select an answer`(page: Page) { + val confirmEpcDetailsPage = + navigator.skipToPropertyRegistrationConfirmEpcDetailsByUprnPage() + confirmEpcDetailsPage.form.submit() + assertThat(confirmEpcDetailsPage.form.getErrorMessage()) + .containsText("Select if you want to use the EPC we found for your property") + } + } + + @Nested + inner class MeesExemptionStepTests { + @Test + fun `User sees a validation error when they do not select a MEES exemption reason`(page: Page) { + val meesExemptionPage = navigator.skipToPropertyRegistrationMeesExemptionPage() + + meesExemptionPage.form.submit() + + assertPageIs(page, MeesExemptionFormPagePropertyRegistration::class) + assertThat(meesExemptionPage.form.getErrorMessage()) + .containsText("Select the energy efficiency exemption you registered for this property") + } + } + + @Nested + inner class EpcExemptionStepTests { + @Test + fun `User sees a validation error when they do not select an EPC exemption reason`(page: Page) { + val epcExemptionPage = navigator.skipToPropertyRegistrationEpcExemptionPage() + + epcExemptionPage.form.submit() + + assertPageIs(page, EpcExemptionFormPagePropertyRegistration::class) + assertThat(epcExemptionPage.form.getErrorMessage()).isVisible() + } + } + + @Nested + inner class Confirmation { + @Test + fun `Navigating here with an incomplete form returns a 400 error page`(page: Page) { + navigator.navigateToPropertyRegistrationConfirmationPage() + val errorPage = assertPageIs(page, ErrorPage::class) + BaseComponent.assertThat(errorPage.heading).containsText("Sorry, there is a problem with the service") + } + } + + @Nested + inner class PropertyRegistrationStepCheckAnswers { + @Test + fun `After changing an answer, submitting a full section saves the state and returns the CYA page`(page: Page) { + val taskListPage = + navigator.goToRestructuredPropertyRegistrationTaskList( + PropertyStateSessionBuilder + .beforePropertyRegistrationCheckAnswers() + .withBedrooms(), + ) + taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + var checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + checkAnswersPage.summaryList.ownershipRow.actions.firstActionLink + .clickAndWait() + val ownershipPage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + + ownershipPage.submitOwnershipType(OwnershipType.LEASEHOLD) + checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + checkAnswersPage.summaryList.licensingRow.actions.firstActionLink + .clickAndWait() + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + + licensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) + val licenceNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyRegistration::class) + licenceNumberPage.submitLicenseNumber("licence number") + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + // Confirmation - verify record saved + val savedJourneyStateCaptor = captor() + verify(savedJourneyStateRepository, times(2)).save(savedJourneyStateCaptor.capture()) + val savedJourneyStateAfterOwnershipUpdate = savedJourneyStateCaptor.allValues[0] + val savedJourneyStateAfterLicensingUpdate = savedJourneyStateCaptor.allValues[1] + assertTrue(savedJourneyStateAfterOwnershipUpdate.serializedState.contains("ownershipType\":\"LEASEHOLD\"")) + assertTrue(savedJourneyStateAfterOwnershipUpdate.serializedState.contains("licensingType\":\"NO_LICENSING\"")) + assertTrue(savedJourneyStateAfterLicensingUpdate.serializedState.contains("licensingType\":\"HMO_ADDITIONAL_LICENCE\"")) + assertTrue(savedJourneyStateAfterLicensingUpdate.serializedState.contains("licenceNumber\":\"licence number\"")) + } + + @Test + fun `the gas supply change link starts a CYA sub-journey that returns to the property registration CYA on submit`(page: Page) { + val taskListPage = + navigator.goToRestructuredPropertyRegistrationTaskList( + PropertyStateSessionBuilder + .beforePropertyRegistrationCheckAnswers() + .withBedrooms(), + ) + taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + checkAnswersPage.complianceSummaryList.gasSupplyRow.clickFirstActionLinkAndWait() + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + hasGasSupplyPage.submitHasNoGasSupply() + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + } + + @Test + fun `the electrical certificate change link navigates to the has electrical certificate page`(page: Page) { + val taskListPage = + navigator.goToRestructuredPropertyRegistrationTaskList( + PropertyStateSessionBuilder + .beforePropertyRegistrationCheckAnswers() + .withBedrooms(), + ) + taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + checkAnswersPage.complianceSummaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } + + @Test + fun `the EPC change link takes the user to the confirm epc step if epc is found by uprn`(page: Page) { + whenever(epcRegisterClient.getByUprn(PropertyRegistrationJourneyTests.uprnForSelectedAddress)) + .thenReturn(MockEpcData.createEpcRegisterClientEpcFoundResponse()) + + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersCompliantEpc(), + ) + + cyaPage.epcCard + .getAction("Change") + .link + .clickAndWait() + assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) + } + + @Test + fun `the EPC change link takes the user to the has epc step if epc is found by certificate number`(page: Page) { + whenever(epcRegisterClient.getByUprn(PropertyRegistrationJourneyTests.uprnForSelectedAddress)) + .thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckAnswersEpcFoundByCertificateNumber(), + ) + cyaPage.epcCard + .getAction("Change") + .link + .clickAndWait() + assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + } + + @Test + fun `the licensing number change link navigates to the licensing page`(page: Page) { + val taskListPage = + navigator.goToRestructuredPropertyRegistrationTaskList( + PropertyStateSessionBuilder + .beforePropertyRegistrationCheckAnswersWithSelectiveLicence() + .withBedrooms(), + ) + taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") + val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + checkAnswersPage.summaryList.licensingNumberRow.clickFirstActionLinkAndWait() + val selectiveLicencePage = assertPageIs(page, SelectiveLicenceFormPagePropertyRegistration::class) + selectiveLicencePage.submitLicenseNumber("SL-99999") + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + } + } + + @Nested + inner class EpcInDateAtStartOfTenancyCheckStep { + @Test + fun `Submitting with no option selected returns an error`() { + val epcInDateAtStartOfTenancyCheckPage = navigator.skipToPropertyRegistrationEpcInDateAtStartOfTenancyCheckPage() + epcInDateAtStartOfTenancyCheckPage.form.submit() + assertThat(epcInDateAtStartOfTenancyCheckPage.form.getErrorMessage()) + .containsText("Select if the EPC was still in date when the current tenancy began") + } + + @Test + fun `Page displays the EPC expiry date in the body text and Yes radio hint`() { + val epcInDateAtStartOfTenancyCheckPage = navigator.skipToPropertyRegistrationEpcInDateAtStartOfTenancyCheckPage() + assertThat(epcInDateAtStartOfTenancyCheckPage.bodyParagraph).containsText("5 January 2022") + assertThat(epcInDateAtStartOfTenancyCheckPage.form.yesHint).containsText("5 January 2022") + } + } + + @Nested + inner class HasMeesExemptionStep { + @Test + fun `Submitting with no option selected returns an error`() { + val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() + hasMeesExemptionPage.form.submit() + assertThat(hasMeesExemptionPage.form.getErrorMessage()) + .containsText("Select if you have a registered energy efficiency exemption for this property") + } + } + + @Nested + inner class EpcMissingStep { + @Test + fun `The page renders the occupied variant for an occupied property`(page: Page) { + val epcMissingPage = navigator.skipToPropertyRegistrationEpcMissingPage(propertyIsOccupied = true) + BaseComponent.assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + BaseComponent.assertThat(epcMissingPage.warning).isVisible() + BaseComponent.assertThat(epcMissingPage.continueAnywayButton).hasText("Continue anyway") + } + + @Test + fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { + val epcMissingPage = navigator.skipToPropertyRegistrationEpcMissingPage(propertyIsOccupied = false) + BaseComponent.assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + BaseComponent.assertThat(epcMissingPage.warning).isHidden() + BaseComponent.assertThat(epcMissingPage.continueButton).hasText("Continue") + } + } + + @Nested + inner class EpcExpiredStep { + @Test + fun `The page renders the occupied variant for an occupied property`(page: Page) { + val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = true) + BaseComponent.assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") + BaseComponent.assertThat(epcExpiredPage.warning).isVisible() + BaseComponent.assertThat(epcExpiredPage.submitButton).hasText("Continue anyway") + } + + @Test + fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { + val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = false) + BaseComponent.assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") + BaseComponent.assertThat(epcExpiredPage.warning).isHidden() + BaseComponent.assertThat(epcExpiredPage.submitButton).hasText("Continue") + } + + @Test + fun `The expiry date is displayed in bold on the occupied variant`(page: Page) { + val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = true) + assertThat(epcExpiredPage.expiryDateParagraph.locator("strong")).hasText("5 January 2022") + } + + @Test + fun `The expiry date is displayed in bold on the unoccupied variant`(page: Page) { + val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = false) + assertThat(epcExpiredPage.expiryDateParagraph.locator("strong")).hasText("5 January 2022") + } + } + + @Nested + inner class LowEnergyRatingStep { + @Test + fun `The page renders the occupied variant for an occupied property`(page: Page) { + val lowEnergyRatingPage = navigator.skipToPropertyRegistrationLowEnergyRatingPage(propertyIsOccupied = true) + BaseComponent.assertThat(lowEnergyRatingPage.heading).containsText( + "This property does not meet energy efficiency requirements for letting", + ) + BaseComponent.assertThat(lowEnergyRatingPage.continueAnywayButton).containsText("Continue anyway") + } + + @Test + fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { + val lowEnergyRatingPage = navigator.skipToPropertyRegistrationLowEnergyRatingPage(propertyIsOccupied = false) + BaseComponent.assertThat(lowEnergyRatingPage.heading).containsText( + "You’ll need to get a new EPC before letting this property", + ) + BaseComponent.assertThat(lowEnergyRatingPage.continueButton).containsText("Continue") + } + } + + @Nested + inner class ProvideEpcLaterStep { + @Test + fun `The page renders the occupied variant for an occupied property`(page: Page) { + val provideEpcLaterPage = navigator.skipToPropertyRegistrationProvideEpcLaterPage(propertyIsOccupied = true) + BaseComponent.assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") + BaseComponent.assertThat(provideEpcLaterPage.insetText).containsText( + "To keep the property registered, we need all its compliance certificates within 28 days.", ) - cyaPage.gasSupplySummaryList.gasSupplyRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + } + + @Test + fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { + val provideEpcLaterPage = navigator.skipToPropertyRegistrationProvideEpcLaterPage(propertyIsOccupied = false) + BaseComponent.assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") + BaseComponent.assertThat(provideEpcLaterPage.insetText).isHidden() + } + } + + @Nested + inner class CheckEpcAnswersStep { + @Test + fun `Shows EPC card with meets requirements inset for a compliant unexpired EPC`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersCompliantEpc(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isVisible() + assertThat(cyaPage.epcExpiredText).isHidden() + assertThat(cyaPage.lowRatingText).isHidden() + assertThat(cyaPage.lowRatingOccupiedInset).isHidden() + assertThat(cyaPage.occupiedNoEpcInset).isHidden() + } + + @Test + fun `Shows EPC card and MEES exemption rows for an unexpired EPC with low rating and exemption`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingWithExemption(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.lowRatingText).isVisible() + assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("Yes") + assertThat(cyaPage.rows.meesExemptionRow.value).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + assertThat(cyaPage.lowRatingOccupiedInset).isHidden() + } + + @Test + fun `Shows EPC card, expired text, tenancy check row, and meets requirements inset for expired but valid EPC`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcInDateAtTenancyStart(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.epcExpiredText).isVisible() + assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") + assertThat(cyaPage.meetsRequirementsInset).isVisible() + assertThat(cyaPage.lowRatingText).isHidden() + } + + @Test + fun `Shows EPC card, expired text, tenancy check, low rating text, and MEES rows for expired EPC with low rating and exemption`( + page: Page, + ) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcLowRatingWithExemption(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.epcExpiredText).isVisible() + assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") + assertThat(cyaPage.lowRatingText).isVisible() + assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("Yes") + assertThat(cyaPage.rows.meesExemptionRow.value).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + } + + @Test + fun `Shows hasEpc row with occupied provide-later text for occupied property choosing to provide EPC later`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersProvideLaterOccupied(), + ) + + assertThat(cyaPage.rows.hasEpcRow.value).containsText("Provide EPC details later") + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + } + + @Test + fun `Shows hasEpc row with unoccupied provide-later text for unoccupied property choosing to provide EPC later`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersProvideLaterUnoccupied(), + ) + + assertThat(cyaPage.rows.hasEpcRow.value).containsText("within 28 days of the property being occupied") + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + } + + @Suppress("ktlint:standard:max-line-length") + @Test + fun `Shows EPC card, low rating text, no exemption row, and council inset for occupied property with low rating and no MEES exemption`( + page: Page, + ) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingNoExemptionOccupied(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.lowRatingText).isVisible() + assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("No") + assertThat(cyaPage.lowRatingOccupiedInset).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + } + + @Test + fun `Shows provide EPC later row for unoccupied property with low rating and no MEES exemption`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingNoExemptionUnoccupied(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + assertThat(cyaPage.rows.hasEpcRow.value) + .containsText("Provide EPC details later (within 28 days of the property being occupied)") + assertThat(cyaPage.lowRatingText).isHidden() + assertThat(cyaPage.lowRatingOccupiedInset).isHidden() + } + + @Test + fun `Shows hasEpc, isEpcRequired, and exemption reason rows for property with no EPC that is exempt`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersNoEpcExempt(), + ) + + assertThat(cyaPage.rows.hasEpcRow.value).containsText("No") + assertThat(cyaPage.rows.isEpcRequiredRow.value).containsText("No") + assertThat(cyaPage.rows.epcExemptionRow.value).isVisible() + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + assertThat(cyaPage.occupiedNoEpcInset).isHidden() + } + + @Suppress("ktlint:standard:max-line-length") + @Test + fun `Shows EPC card, expired text, tenancy check, low rating text, no exemption row, and council inset for occupied property with expired low-rating EPC in date at tenancy start and no exemption`( + page: Page, + ) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcLowRatingNoExemptionOccupied(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.epcExpiredText).isVisible() + assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") + assertThat(cyaPage.lowRatingText).isVisible() + assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("No") + assertThat(cyaPage.lowRatingOccupiedInset).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + } + + @Test + fun `Shows hasEpc and isEpcRequired rows with council inset for occupied property with no EPC that is required`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersNoEpcOccupiedNotExempt(), + ) + + assertThat(cyaPage.rows.hasEpcRow.value).containsText("No") + assertThat(cyaPage.rows.isEpcRequiredRow.value).containsText("Yes") + assertThat(cyaPage.occupiedNoEpcInset).isVisible() + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + assertThat(cyaPage.rows.epcExemptionRow.key).isHidden() + } + } + + @Nested + inner class ConfirmMissingComplianceStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val confirmPage = navigator.skipToPropertyRegistrationConfirmMissingCompliancePage() + confirmPage.form.submit() + assertThat(confirmPage.form.getErrorMessage()).containsText("Select whether you want to submit this registration") + } + + @Test + fun `Selecting no, go back redirects to the check answers page`(page: Page) { + val confirmPage = navigator.skipToPropertyRegistrationConfirmMissingCompliancePage() + confirmPage.form.radios.selectValue("false") + confirmPage.form.submit() + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + } } + } + + // TODO PDJB-1340: Remove tests when the PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING Feature Flag is removed + @Nested + inner class RestructureAndSkippingDisabled { + @BeforeEach + fun disableRestructureAndSkippingFlag() { + featureFlagManager.disableFeature(PROPERTY_REGISTRATION_RESTRUCTURE_AND_SKIPPING) + } + + @Nested + inner class TaskListStep { + @Test + fun `Completing preceding steps will show a task as not started and completed steps as complete`(page: Page) { + navigator.skipToPropertyRegistrationHasJointLandlordsPage() + val taskListPage = navigator.goToPropertyRegistrationTaskList() + assert(taskListPage.taskHasStatus("Property address", "Complete")) + assert(taskListPage.taskHasStatus("Property type", "Complete")) + assert(taskListPage.taskHasStatus("How you own the property", "Complete")) + assert(taskListPage.taskHasStatus("If the property has a license", "Complete")) + assert(taskListPage.taskHasStatus("Tenancy and rental information", "Complete")) + assert(taskListPage.taskHasStatus("Invite joint landlords", "Not started")) + assert(taskListPage.taskHasStatus("Gas safety certificate", "Cannot start yet")) + assert(taskListPage.taskHasStatus("Electrical safety certificate", "Cannot start yet")) + assert(taskListPage.taskHasStatus("Energy performance certificate (EPC)", "Cannot start yet")) + } + + @Test + fun `EPC task (starting with an internal step) shows as Not Started when the user is on the first step they see`(page: Page) { + navigator.skipToPropertyRegistrationHasEpcPage() + val taskListPage = navigator.goToPropertyRegistrationTaskList() + assert(taskListPage.taskHasStatus("Energy performance certificate (EPC)", "Not started")) + } + + @Test + fun `Completing first step of a task will show a task as in progress and completed steps as complete`(page: Page) { + navigator.skipToPropertyRegistrationRentFrequencyPage() + val taskListPage = navigator.goToPropertyRegistrationTaskList() + assert(taskListPage.taskHasStatus("Property address", "Complete")) + assert(taskListPage.taskHasStatus("Property type", "Complete")) + assert(taskListPage.taskHasStatus("How you own the property", "Complete")) + assert(taskListPage.taskHasStatus("If the property has a license", "Complete")) + assert(taskListPage.taskHasStatus("Tenancy and rental information", "In progress")) + assert(taskListPage.taskHasStatus("Invite joint landlords", "Cannot start yet")) + assert(taskListPage.taskHasStatus("Gas safety certificate", "Cannot start yet")) + assert(taskListPage.taskHasStatus("Electrical safety certificate", "Cannot start yet")) + assert(taskListPage.taskHasStatus("Energy performance certificate (EPC)", "Cannot start yet")) + } + } + + @Nested + inner class LookupAddressAndNoAddressFoundSteps { + @Test + fun `Submitting with empty data fields returns an error`(page: Page) { + val lookupAddressPage = navigator.goToPropertyRegistrationLookupAddressPage() + lookupAddressPage.clearForm() // There may be form answers in the journey state + lookupAddressPage.form.submit() + assertThat(lookupAddressPage.form.getErrorMessage("postcode")).containsText("Enter a postcode") + assertThat(lookupAddressPage.form.getErrorMessage("houseNameOrNumber")).containsText("Enter a house name or number") + } + + @Test + fun `If no English addresses are found, user can search again or enter address manually via the No Address Found step`( + page: Page, + ) { + // Lookup address finds no English results + val houseNumber = "NOT A HOUSE NUMBER" + val postcode = "NOT A POSTCODE" + var lookupAddressPage = navigator.goToPropertyRegistrationLookupAddressPage() + lookupAddressPage.submitPostcodeAndBuildingNameOrNumber(postcode, houseNumber) + + // redirect to noAddressFoundPage + var noAddressFoundPage = assertPageIs(page, NoAddressFoundFormPagePropertyRegistration::class) + BaseComponent + .assertThat(noAddressFoundPage.heading) + .containsText("No matching address in England found for $postcode and $houseNumber") + + // Search Again + noAddressFoundPage.searchAgain.clickAndWait() + lookupAddressPage = assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + lookupAddressPage.submitPostcodeAndBuildingNameOrNumber(postcode, houseNumber) + + // Submit no address found page + noAddressFoundPage = assertPageIs(page, NoAddressFoundFormPagePropertyRegistration::class) + noAddressFoundPage.form.submit() + assertPageIs(page, ManualAddressFormPagePropertyRegistration::class) + } + } + + @Nested + inner class SelectAddressStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage() + selectAddressPage.form.submit() + assertThat(selectAddressPage.form.getErrorMessage()).containsText("Select an address") + } + + @Test + fun `Clicking Search Again navigates to the previous step`(page: Page) { + val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage() + selectAddressPage.searchAgain.clickAndWait() + assertPageIs(page, LookupAddressFormPagePropertyRegistration::class) + } + + @Test + fun `Selecting an already-registered address navigates to the AlreadyRegistered step`(page: Page) { + val alreadyRegisteredAddress = AddressDataModel("1 Example Road", uprn = 1123456) + val selectAddressPage = navigator.skipToPropertyRegistrationSelectAddressPage(listOf(alreadyRegisteredAddress)) + selectAddressPage.selectAddressAndSubmit(alreadyRegisteredAddress.singleLineAddress) + assertPageIs(page, AlreadyRegisteredFormPagePropertyRegistration::class) + } + } + + @Nested + inner class ManualAddressEntryStep { + @Test + fun `Submitting empty data fields returns errors`(page: Page) { + val manualAddressPage = navigator.skipToPropertyRegistrationManualAddressPage() + manualAddressPage.submitAddress() + assertThat(manualAddressPage.form.getErrorMessage("addressLineOne")) + .containsText("Enter the first line of an address, typically the building and street") + assertThat(manualAddressPage.form.getErrorMessage("townOrCity")).containsText("Enter town or city") + assertThat(manualAddressPage.form.getErrorMessage("postcode")).containsText("Enter postcode") + } + } + + @Nested + inner class SelectLocalCouncilStep { + @Test + fun `Submitting without selecting an LA return an error`(page: Page) { + val selectLocalCouncilPage = navigator.skipToPropertyRegistrationSelectLocalCouncilPage() + selectLocalCouncilPage.form.submit() + assertThat(selectLocalCouncilPage.form.getErrorMessage("localCouncilId")) + .containsText("Select a local council to continue") + } + } + + @Nested + inner class PropertyTypeStep { + @Test + fun `Submitting with no propertyType selected returns an error`(page: Page) { + val propertyTypePage = navigator.skipToPropertyRegistrationPropertyTypePage() + propertyTypePage.form.submit() + assertThat(propertyTypePage.form.getErrorMessage()).containsText("Select the type of property") + } + + @Test + fun `Submitting with the Other propertyType selected but an empty customPropertyType field returns an error`(page: Page) { + val propertyTypePage = navigator.skipToPropertyRegistrationPropertyTypePage() + propertyTypePage.submitCustomPropertyType("") + assertThat(propertyTypePage.form.getErrorMessage()).containsText("Enter the property type") + } + } + + @Nested + inner class OwnershipTypeStep { + @Test + fun `Submitting with no ownershipType selected returns an error`(page: Page) { + val ownershipTypePage = navigator.skipToPropertyRegistrationOwnershipTypePage() + ownershipTypePage.form.submit() + assertThat(ownershipTypePage.form.getErrorMessage()).containsText("Select the ownership type") + } + } + + @Nested + inner class LicensingTypeStep { + @Test + fun `Submitting with no licensingType selected returns an error`(page: Page) { + val licensingTypePage = navigator.skipToPropertyRegistrationLicensingTypePage() + licensingTypePage.form.submit() + assertThat(licensingTypePage.form.getErrorMessage()).containsText("Select the type of licensing for the property") + } + + @Test + fun `Submitting with an HMO mandatory licence redirects to the next step`(page: Page) { + val licensingTypePage = navigator.skipToPropertyRegistrationLicensingTypePage() + licensingTypePage.submitLicensingType(LicensingType.HMO_MANDATORY_LICENCE) + val licenseNumberPage = assertPageIs(page, HmoMandatoryLicenceFormPagePropertyRegistration::class) + BaseComponent + .assertThat(licenseNumberPage.form.sectionHeader) + .containsText("Section 1 of 2 — Add property details") + } + + @Test + fun `Submitting with an HMO additional licence redirects to the next step`(page: Page) { + val licensingTypePage = navigator.skipToPropertyRegistrationLicensingTypePage() + licensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) + val licenseNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyRegistration::class) + BaseComponent + .assertThat(licenseNumberPage.form.sectionHeader) + .containsText("Section 1 of 2 — Add property details") + } + } + + @Nested + inner class SelectiveLicenceStep { + @Test + fun `Submitting with no licence number returns an error`(page: Page) { + val selectiveLicencePage = navigator.skipToPropertyRegistrationSelectiveLicencePage() + selectiveLicencePage.form.submit() + assertThat(selectiveLicencePage.form.getErrorMessage()).containsText("Enter the selective licence number") + } + + @Test + fun `Submitting with a very long licence number returns an error`(page: Page) { + val selectiveLicencePage = navigator.skipToPropertyRegistrationSelectiveLicencePage() + val aVeryLongString = + "This string is very long, so long that it is not feasible that it is a real licence number " + + "- therefore if it is submitted there will in fact be an error rather than a successful submission." + + " It is actually quite difficult for a string to be long enough to trigger this error, because the" + + " maximum length has been selected to be permissive of id numbers we do not expect while still having " + + "a cap reachable with a little effort." + selectiveLicencePage.submitLicenseNumber(aVeryLongString) + assertThat(selectiveLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") + } + } + + @Nested + inner class HmoMandatoryLicenceStep { + @Test + fun `Submitting with a licence number redirects to the next step`(page: Page) { + val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationHmoMandatoryLicencePage() + hmoMandatoryLicencePage.submitLicenseNumber("licence number") + assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + } + + @Test + fun `Submitting with no licence number returns an error`(page: Page) { + val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationHmoMandatoryLicencePage() + hmoMandatoryLicencePage.form.submit() + assertThat(hmoMandatoryLicencePage.form.getErrorMessage()).containsText("Enter the HMO Mandatory licence number") + } + + @Test + fun `Submitting with a very long licence number returns an error`(page: Page) { + val hmoMandatoryLicencePage = navigator.skipToPropertyRegistrationHmoMandatoryLicencePage() + val aVeryLongString = + "This string is very long, so long that it is not feasible that it is a real licence number " + + "- therefore if it is submitted there will in fact be an error rather than a successful submission." + + " It is actually quite difficult for a string to be long enough to trigger this error, because the" + + " maximum length has been selected to be permissive of id numbers we do not expect while still having " + + "a cap reachable with a little effort." + hmoMandatoryLicencePage.submitLicenseNumber(aVeryLongString) + assertThat(hmoMandatoryLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") + } + } + + @Nested + inner class HmoAdditionalLicenceStep { + @Test + fun `Submitting with a licence number redirects to the next step`(page: Page) { + val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationHmoAdditionalLicencePage() + hmoAdditionalLicencePage.submitLicenseNumber("licence number") + assertPageIs(page, OccupancyFormPagePropertyRegistration::class) + } + + @Test + fun `Submitting with no licence number returns an error`(page: Page) { + val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationHmoAdditionalLicencePage() + hmoAdditionalLicencePage.form.submit() + assertThat(hmoAdditionalLicencePage.form.getErrorMessage()).containsText("Enter the HMO additional licence number") + } + + @Test + fun `Submitting with a very long licence number returns an error`(page: Page) { + val hmoAdditionalLicencePage = navigator.skipToPropertyRegistrationHmoAdditionalLicencePage() + val aVeryLongString = + "This string is very long, so long that it is not feasible that it is a real licence number " + + "- therefore if it is submitted there will in fact be an error rather than a successful submission." + + " It is actually quite difficult for a string to be long enough to trigger this error, because the" + + " maximum length has been selected to be permissive of id numbers we do not expect while still having " + + "a cap reachable with a little effort." + hmoAdditionalLicencePage.submitLicenseNumber(aVeryLongString) + assertThat(hmoAdditionalLicencePage.form.getErrorMessage()).containsText("The licensing number is too long") + } + } + + @Nested + inner class OccupancyStep { + @Test + fun `Submitting with no occupancy option selected returns an error`(page: Page) { + val occupancyPage = navigator.skipToPropertyRegistrationOccupancyPage() + occupancyPage.form.submit() + assertThat(occupancyPage.form.getErrorMessage()).containsText("Select whether the property is occupied") + } + } + + @Nested + inner class NumberOfHouseholdsStep { + @Test + fun `Submitting with a blank numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() + householdsPage.form.submit() + assertThat(householdsPage.form.getErrorMessage()).containsText("Enter how many separate households, like 1 or 2") + } + + @Test + fun `Submitting with a non-numerical value in the numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() + householdsPage.submitNumberOfHouseholds("not-a-number") + assertThat(householdsPage.form.getErrorMessage()) + .containsText("Enter how many separate households, like 1 or 2") + } + + @Test + fun `Submitting with a non-integer number in the numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() + householdsPage.submitNumberOfHouseholds("2.3") + assertThat(householdsPage.form.getErrorMessage()) + .containsText("Enter how many separate households, like 1 or 2") + } + + @Test + fun `Submitting with a negative integer in the numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() + householdsPage.submitNumberOfHouseholds(-2) + assertThat(householdsPage.form.getErrorMessage()) + .containsText("Enter how many separate households, like 1 or 2") + } + + @Test + fun `Submitting with a zero integer in the numberOfHouseholds field returns an error`(page: Page) { + val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() + householdsPage.submitNumberOfHouseholds(0) + assertThat(householdsPage.form.getErrorMessage()) + .containsText("Enter how many separate households, like 1 or 2") + } + } + + @Nested + inner class NumberOfPeopleStep { + @Test + fun `Submitting with a blank numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() + peoplePage.form.submit() + assertThat(peoplePage.form.getErrorMessage()).containsText("Enter how many people, like 2 or 5") + } + + @Test + fun `Submitting with a non-numerical value in the numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() + peoplePage.submitNumOfPeople("not-a-number") + assertThat(peoplePage.form.getErrorMessage()) + .containsText("Enter how many people, like 2 or 5") + } + + @Test + fun `Submitting with a non-integer number in the numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() + peoplePage.submitNumOfPeople("2.3") + assertThat(peoplePage.form.getErrorMessage()) + .containsText("Enter how many people, like 2 or 5") + } + + @Test + fun `Submitting with a negative integer in the numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() + peoplePage.submitNumOfPeople("-2") + assertThat(peoplePage.form.getErrorMessage()) + .containsText("Enter how many people, like 2 or 5") + } + + @Test + fun `Submitting with a zero integer in the numberOfPeople field returns an error`(page: Page) { + val peoplePage = navigator.skipToPropertyRegistrationPeoplePage() + peoplePage.submitNumOfPeople(0) + assertThat(peoplePage.form.getErrorMessage()) + .containsText("Enter how many people, like 2 or 5") + } + + @Test + fun `Submitting with an integer in the numberOfPeople field that is less than the numberOfHouseholds returns an error`( + page: Page, + ) { + val householdsPage = navigator.skipToPropertyRegistrationHouseholdsPage() + householdsPage.submitNumberOfHouseholds(3) + val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) + peoplePage.submitNumOfPeople(2) + assertThat(peoplePage.form.getErrorMessage()) + .containsText( + "The number of people in the property must be the same as or higher than the number of households in the property", + ) + } + } + + @Nested + inner class NumberOfBedroomsStep { + val numberOfBedroomsErrorMessage = "Enter the number of bedrooms, like 3 or 8" + + @Test + fun `Submitting with a blank numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.form.submit() + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) + } + + @Test + fun `Submitting with a non-numerical value in the numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.submitNumOfBedrooms("not-a-number") + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) + } + + @Test + fun `Submitting with a non-integer number in the numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.submitNumOfBedrooms("2.3") + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) + } + + @Test + fun `Submitting with a negative integer in the numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.submitNumOfBedrooms("-2") + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) + } + + @Test + fun `Submitting with a zero integer in the numberOfBedrooms field returns an error`(page: Page) { + val bedroomsPage = navigator.skipToPropertyRegistrationBedroomsPage() + bedroomsPage.submitNumOfBedrooms(0) + assertThat(bedroomsPage.form.getErrorMessage()).containsText(numberOfBedroomsErrorMessage) + } + } + + @Nested + inner class RentIncludesBillsStep { + @Test + fun `Submitting with no rent included option selected returns an error`(page: Page) { + val rentIncludesBillsPage = navigator.skipToPropertyRegistrationRentIncludesBillsPage() + rentIncludesBillsPage.form.submit() + assertThat(rentIncludesBillsPage.form.getErrorMessage()).containsText("Select whether the rent includes bills") + } + } + + @Nested + inner class BillsIncludedStep { + @Test + fun `Submitting with no bills included selected returns an error`(page: Page) { + val billsIncludedPage = navigator.skipToPropertyRegistrationBillsIncludedPage() + billsIncludedPage.form.submit() + assertThat(billsIncludedPage.form.getErrorMessage()).containsText("Select what you include in the rent") + } + + @Test + fun `Submitting with something else selected but no text entered returns an error`(page: Page) { + val billsIncludedPage = navigator.skipToPropertyRegistrationBillsIncludedPage() + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.selectSomethingElseCheckbox() + billsIncludedPage.form.submit() + assertThat(billsIncludedPage.form.getErrorMessage()).containsText("Enter the bills and services you include in the rent") + } + + @Test + fun `Submitting with a very long something else text returns an error`(page: Page) { + val billsIncludedPage = navigator.skipToPropertyRegistrationBillsIncludedPage() + billsIncludedPage.selectGasElectricityWater() + billsIncludedPage.selectSomethingElseCheckbox() + val aVeryLongString = + "This string is very long, so long that it is not feasible that it is a real description " + + "- therefore if it is submitted there will in fact be an error rather than a successful submission." + + " It is actually quite difficult for a string to be long enough to trigger this error, because the" + + " maximum length has been selected to be permissive of descriptions we do not expect while still having " + + "a cap reachable with a little effort." + billsIncludedPage.fillCustomBills(aVeryLongString) + billsIncludedPage.form.submit() + assertThat(billsIncludedPage.form.getErrorMessage("customBillsIncluded")) + .containsText("The description of other bills and services must be 200 characters or fewer") + } + } + + @Nested + inner class FurnishedStatusStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val furnishedStatusPage = navigator.skipToPropertyRegistrationFurnishedStatusPage() + furnishedStatusPage.form.submit() + assertThat( + furnishedStatusPage.form.getErrorMessage(), + ).containsText("Select whether the property is furnished, partly furnished or unfurnished") + } + } + + @Nested + inner class RentFrequencyStep { + @Test + fun `Submitting with no rentFrequency selected returns an error`(page: Page) { + val rentFrequencyPage = navigator.skipToPropertyRegistrationRentFrequencyPage() + rentFrequencyPage.form.submit() + assertThat(rentFrequencyPage.form.getErrorMessage()).containsText("Select how often you charge rent") + } + + @Test + fun `Submitting with other rent frequency selected but no text entered returns an error`(page: Page) { + val rentFrequencyPage = navigator.skipToPropertyRegistrationRentFrequencyPage() + rentFrequencyPage.selectRentFrequency(RentFrequency.OTHER) + rentFrequencyPage.form.submit() + assertThat(rentFrequencyPage.form.getErrorMessage()).containsText("Enter how often you charge rent") + } + } + + @Nested + inner class RentAmountStep { + @Test + fun `Submitting no rentAmount returns an error`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() + rentAmountPage.form.submit() + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + } + + @Test + fun `Submitting a rentAmount greater than two decimals returns an error`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() + rentAmountPage.submitRentAmount("400.123") + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + } + + @Test + fun `Submitting a negative rentAmount returns an error`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() + rentAmountPage.submitRentAmount("-400.12") + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + } + + @Test + fun `Submitting a non-numerical rentAmount returns an error`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() + rentAmountPage.submitRentAmount("not-a-number") + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + } + + @Test + fun `Submitting a rentAmount of 10000000 or above returns an error`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage() + rentAmountPage.submitRentAmount("10000000") + assertThat( + rentAmountPage.form.getErrorMessage(), + ).containsText("Rent amount must only include numbers (and a decimal point), like 600 or 193.54") + } + + @Nested + inner class ConditionalContentPerRentFrequency { + @Test + fun `Page renders correctly for weekly rent frequency`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.WEEKLY) + BaseComponent + .assertThat(rentAmountPage.header) + .containsText("What is the weekly rent?") + BaseComponent + .assertThat(rentAmountPage.subheading) + .containsText("Weekly rent") + BaseComponent + .assertThat(rentAmountPage.billsExplanationForRentFrequency) + .containsText("The amount you enter must be the total weekly rent agreed with the tenant.") + BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() + } + + @Test + fun `Page renders correctly for four weekly rent frequency`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.FOUR_WEEKLY) + BaseComponent + .assertThat(rentAmountPage.header) + .containsText("What is the 4-weekly rent?") + BaseComponent + .assertThat(rentAmountPage.subheading) + .containsText("4-weekly rent") + BaseComponent + .assertThat(rentAmountPage.billsExplanationForRentFrequency) + .containsText("The amount you enter must be the total 4-weekly rent agreed with the tenant.") + BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() + } + + @Test + fun `Page renders correctly for monthly rent frequency`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.MONTHLY) + BaseComponent + .assertThat(rentAmountPage.header) + .containsText("What is the monthly rent?") + BaseComponent + .assertThat(rentAmountPage.subheading) + .containsText("Monthly rent") + BaseComponent + .assertThat(rentAmountPage.billsExplanationForRentFrequency) + .containsText("The amount you enter must be the total monthly rent agreed with the tenant.") + BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isHidden() + } + + @Test + fun `Page renders correctly for 'other' rent frequency`(page: Page) { + val rentAmountPage = navigator.skipToPropertyRegistrationRentAmountPage(RentFrequency.OTHER) + BaseComponent + .assertThat(rentAmountPage.header) + .containsText("What is the monthly rent?") + BaseComponent + .assertThat(rentAmountPage.subheading) + .containsText("Monthly rent") + BaseComponent + .assertThat(rentAmountPage.billsExplanationForRentFrequency) + .containsText("The amount you enter must be the total monthly rent agreed with the tenant.") + BaseComponent.assertThat(rentAmountPage.rentCalculationParagraph).isVisible() + } + } + } + + @Nested + inner class HasJointLandlordsStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val hasJointLandlordsPage = navigator.skipToPropertyRegistrationHasJointLandlordsPage() + hasJointLandlordsPage.form.submit() + assertThat(hasJointLandlordsPage.form.getErrorMessage()) + .containsText("Select if there are any other landlords for this property") + } + + @Test + fun `The link renders correctly`(page: Page) { + val hasJointLandlordsPage = navigator.skipToPropertyRegistrationHasJointLandlordsPage() + BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("href", GOV_LEGAL_ADVICE_URL) + BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("rel", "noreferrer noopener") + BaseComponent.assertThat(hasJointLandlordsPage.legalAdviceLink).hasAttribute("target", "_blank") + } + } + + @Nested + inner class ManagingJointLandlords { + @Test + fun `Submitting remove a joint landlord with no option selected returns an error`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") + + val checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + + val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.form.submit() + assertThat(removeJointLandlordPage.form.getErrorMessage()) + .containsText("Select if you want to remove this joint landlord") + } + + @Test + fun `Submitting remove a joint landlord with No selected returns to the check page without removing the landlord`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") + + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + + val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.submitDoesNotWantToProceed() + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + } + + @Test + fun `Clicking cancel returns to the check page regardless of selected remove answer`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") + + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.form.addAnotherButton.clickAndWait() + + val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + inviteAnotherJointLandlordPage.submitEmail("beta@example.com") + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + + var removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.form.areYouSureRadios.selectValue("true") + removeJointLandlordPage.cancelLink.clickAndWait() + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + + removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.form.areYouSureRadios.selectValue("false") + removeJointLandlordPage.cancelLink.clickAndWait() + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") + } + + @Test + fun `Removing joint landlords works as expected`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") + + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.form.addAnotherButton.clickAndWait() + + val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + inviteAnotherJointLandlordPage.submitEmail("beta@example.com") + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + + var removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.submitWantsToProceed() + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("beta@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + + removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.submitWantsToProceed() + + assertPageIs(page, HasJointLandlordsFormBasePagePropertyRegistration::class) + } + + @Test + fun `Editing joint landlords works as expected`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") + + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.form.addAnotherButton.clickAndWait() + + var inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + inviteAnotherJointLandlordPage.submitEmail("beta@example.com") + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Change") + + inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + BaseComponent.assertThat(inviteAnotherJointLandlordPage.form.emailInput).hasValue("alpha@example.com") + inviteAnotherJointLandlordPage.submitEmail("gamma@example.com") + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("gamma@example.com") + } + + @Test + fun `Numbering on page and tables is correct`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("alpha@example.com") + + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") + assertThat(checkJointLandlordPage.summaryList.firstRow.key).containsText("Joint landlord 1") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("alpha@example.com") + checkJointLandlordPage.form.addAnotherButton.clickAndWait() + + val inviteAnotherJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + inviteAnotherJointLandlordPage.submitEmail("beta@example.com") + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 2 joint landlords") + assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).key).containsText("Joint landlord 2") + assertThat(checkJointLandlordPage.summaryList.getRowByIndex(1).value).containsText("beta@example.com") + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Remove") + + val removeJointLandlordPage = assertPageIs(page, RemoveJointLandlordAreYouSureFormPagePropertyRegistration::class) + removeJointLandlordPage.submitWantsToProceed() + + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + BaseComponent.assertThat(checkJointLandlordPage.title).containsText("You’ve added 1 joint landlord") + assertThat(checkJointLandlordPage.summaryList.firstRow.key).containsText("Joint landlord 1") + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText("beta@example.com") + } + } + + @Nested + inner class InviteJointLandlordsStep { + @Test + fun `Submitting with no email returns an error`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("") + assertThat(inviteJointLandlordsPage.form.getErrorMessage()) + .containsText("Enter an email address in the correct format, like name@example.com") + } - @Test - fun `Uploaded cert - gas supply change link navigates to has gas supply page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), - ) - cyaPage.gasSupplySummaryList.gasSupplyRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + @Test + fun `Submitting with an invalid email returns an error`(page: Page) { + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail("not-an-email") + assertThat(inviteJointLandlordsPage.form.getErrorMessage()) + .containsText("Enter an email address in the correct format, like name@example.com") + } } - @Test - fun `Uploaded cert - valid gas cert change link navigates to has gas cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), - ) - cyaPage.certSummaryList.validGasCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - } + @Nested + inner class InviteAnotherJointLandlordsStep { + @Test + fun `Submitting with an already invited email returns an error`(page: Page) { + val alreadyInvitedEmail = "already@invited.com" + val inviteJointLandlordsPage = + navigator.skipToPropertyRegistrationInviteAnotherJointLandlordPage(mutableListOf(alreadyInvitedEmail)) + inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) + assertThat(inviteJointLandlordsPage.form.getErrorMessage()) + .containsText("You have already invited this email address") + } - @Test - fun `Uploaded cert - issue date change link navigates to issue date page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), - ) - cyaPage.certSummaryList.issueDateRow.clickFirstActionLinkAndWait() - assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) - } + @Test + fun `Submitting with an invited email in edit mode is permitted`(page: Page) { + val alreadyInvitedEmail = "already@invited.com" - @Test - fun `Uploaded cert - certificate change link navigates to check uploads page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), - ) - cyaPage.certSummaryList.yourCertificateRow.clickFirstActionLinkAndWait() - assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) - } + val inviteJointLandlordsPage = navigator.skipToPropertyRegistrationInviteJointLandlordPage() + inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) - @Test - fun `Provide later - gas cert change link navigates to has gas cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersProvideLater(), - ) - cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - } + var checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + checkJointLandlordPage.summaryList.firstRow.clickNamedActionLinkAndWait("Change") - @Test - fun `No cert - gas cert change link navigates to has gas cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersNoCert(), - ) - cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) - } + val editJointLandlordPage = assertPageIs(page, InviteAnotherJointLandlordFormPagePropertyRegistration::class) + BaseComponent.assertThat(editJointLandlordPage.form.emailInput).hasValue(alreadyInvitedEmail) + inviteJointLandlordsPage.submitEmail(alreadyInvitedEmail) - @Test - fun `Cert expired - gas cert change link navigates to has gas cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersCertExpired(), - ) - cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + checkJointLandlordPage = assertPageIs(page, CheckJointLandlordsFormPagePropertyRegistration::class) + assertThat(checkJointLandlordPage.summaryList.firstRow.value).containsText(alreadyInvitedEmail) + } } - } - @Nested - inner class HasElectricalCertStep { - @Test - fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { - val hasElectricalCertPage = navigator.skipToPropertyRegistrationHasElectricalCertPage() - hasElectricalCertPage.form.submitPrimaryButton() - assertThat( - hasElectricalCertPage.form.getErrorMessage(), - ).containsText("Select which electrical safety certificate you have") - } - } + @Nested + inner class HasGasSupplyStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage() + hasGasSupplyPage.form.submit() + assertThat( + hasGasSupplyPage.form.getErrorMessage(), + ).containsText("Select whether you have a gas supply or any gas appliances") + } - @Nested - inner class CheckElectricalSafetyAnswersStep { - @Test - fun `Cert uploaded EIC - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + @Test + fun `Submitting No navigates to the check you gas answers step`(page: Page) { + val hasGasSupplyPage = navigator.skipToPropertyRegistrationHasGasSupplyPage() + hasGasSupplyPage.submitHasNoGasSupply() + assertPageIs(page, CheckGasSafetyAnswersFormPagePropertyRegistration::class) + } } - @Test - fun `Cert uploaded EIC - expiry date change link navigates to expiry date page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), - ) - cyaPage.summaryList.expiryDateRow.clickFirstActionLinkAndWait() - assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + @Nested + inner class HasGasSafetyCertStep { + @Test + fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { + val hasGasSafetyCertPage = navigator.skipToPropertyRegistrationHasGasCertPage() + hasGasSafetyCertPage.form.submitPrimaryButton() + assertThat( + hasGasSafetyCertPage.form.getErrorMessage(), + ).containsText("Select whether you have a gas safety certificate") + } } - @Test - fun `Cert uploaded EIC - certificate change link navigates to check uploads page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), - ) - cyaPage.summaryList.yourCertificateRow.clickFirstActionLinkAndWait() - assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + @Nested + inner class GasSafetyIssueDateStepTests { + @ParameterizedTest(name = "{0}") + @Suppress("ktlint:standard:max-line-length") + @MethodSource( + "uk.gov.communities.prsdb.webapp.testHelpers.parameterProviders.TodayOrPastDateValidationTestParameterProvider#provideInvalidDateStrings", + ) + fun `Submitting returns a corresponding error when`( + dayMonthYear: Triple, + expectedErrorMessage: String, + ) { + val (day, month, year) = dayMonthYear + val gasSafetyIssueDatePage = navigator.skipToPropertyRegistrationGasCertIssueDatePage() + gasSafetyIssueDatePage.submitDate(day, month, year) + assertThat(gasSafetyIssueDatePage.form.getErrorMessage()).containsText(expectedErrorMessage) + } } - @Test - fun `Cert uploaded EICR - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEicr(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } + @Nested + inner class CheckGasSafetyAnswersStep { + @Test + fun `No gas supply - gas supply change link navigates to has gas supply page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersNoGasSupply(), + ) + cyaPage.gasSupplySummaryList.gasSupplyRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + } - @Test - fun `Provide later - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersProvideLater(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } + @Test + fun `Uploaded cert - gas supply change link navigates to has gas supply page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), + ) + cyaPage.gasSupplySummaryList.gasSupplyRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + } - @Test - fun `No cert - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersNoCert(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } + @Test + fun `Uploaded cert - valid gas cert change link navigates to has gas cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), + ) + cyaPage.certSummaryList.validGasCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + } - @Test - fun `Cert expired - cert type change link navigates to has electrical cert page`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersCertExpired(), - ) - cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } - } + @Test + fun `Uploaded cert - issue date change link navigates to issue date page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), + ) + cyaPage.certSummaryList.issueDateRow.clickFirstActionLinkAndWait() + assertPageIs(page, GasCertIssueDateFormPagePropertyRegistration::class) + } - @Nested - inner class ElectricalCertExpiryDateStepTests { - @ParameterizedTest(name = "{0}") - @Suppress("ktlint:standard:max-line-length") - @MethodSource( - "uk.gov.communities.prsdb.webapp.testHelpers.parameterProviders.AnyDateValidationTestParameterProvider#provideInvalidDateStrings", - ) - fun `Submitting returns a corresponding error when`( - dayMonthYear: Triple, - expectedErrorMessage: String, - ) { - val (day, month, year) = dayMonthYear - val electricalCertExpiryDatePage = navigator.skipToPropertyRegistrationElectricalCertExpiryDatePage() - electricalCertExpiryDatePage.submitDate(day, month, year) - assertThat(electricalCertExpiryDatePage.form.getErrorMessage()).containsText(expectedErrorMessage) - } - } + @Test + fun `Uploaded cert - certificate change link navigates to check uploads page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersUploadedCert(), + ) + cyaPage.certSummaryList.yourCertificateRow.clickFirstActionLinkAndWait() + assertPageIs(page, CheckGasCertUploadsFormPagePropertyRegistration::class) + } - @Nested - inner class HasEpcStepTests { - @Test - fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { - val hasEpcPage = navigator.skipToPropertyRegistrationHasEpcPage() - hasEpcPage.form.submitPrimaryButton() - assertThat(hasEpcPage.form.getErrorMessage()) - .containsText("Select if you have an EPC for this property") - } - } + @Test + fun `Provide later - gas cert change link navigates to has gas cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersProvideLater(), + ) + cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + } - @Nested - inner class FindYourEpcStepTests { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() - findYourEpcPage.form.submit() - assertThat(findYourEpcPage.form.getErrorMessage()) - .containsText("Enter a certificate number") - } - } + @Test + fun `No cert - gas cert change link navigates to has gas cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersNoCert(), + ) + cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + } - @Nested - inner class ConfirmEpcDetailsRetrievedByCertificateNumberStepTests { - @Test - fun `User sees a validation error when they do not select an answer`(page: Page) { - val confirmEpcDetailsPage = - navigator.skipToPropertyRegistrationConfirmEpcDetailsRetrievedByCertificateNumberPage() - confirmEpcDetailsPage.form.submit() - assertThat(confirmEpcDetailsPage.form.getErrorMessage()) - .containsText("Select if you want to use this EPC") + @Test + fun `Cert expired - gas cert change link navigates to has gas cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckGasSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckGasSafetyAnswersCertExpired(), + ) + cyaPage.gasSupplySummaryList.gasCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasGasCertFormPagePropertyRegistration::class) + } } - } - @Nested - inner class IsEpcRequiredStepTests { - @Test - fun `Submitting with no option selected returns a validation error`(page: Page) { - val isEpcRequiredPage = navigator.skipToPropertyRegistrationIsEpcRequiredPage() - isEpcRequiredPage.form.submit() - assertThat(isEpcRequiredPage.form.getErrorMessage()) - .containsText("Select if an EPC is required to let this property") + @Nested + inner class HasElectricalCertStep { + @Test + fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { + val hasElectricalCertPage = navigator.skipToPropertyRegistrationHasElectricalCertPage() + hasElectricalCertPage.form.submitPrimaryButton() + assertThat( + hasElectricalCertPage.form.getErrorMessage(), + ).containsText("Select which electrical safety certificate you have") + } } - } - @Nested - inner class ConfirmEpcDetailsByUprnStepTests { - @Test - fun `User sees a validation error when they do not select an answer`(page: Page) { - val confirmEpcDetailsPage = - navigator.skipToPropertyRegistrationConfirmEpcDetailsByUprnPage() - confirmEpcDetailsPage.form.submit() - assertThat(confirmEpcDetailsPage.form.getErrorMessage()) - .containsText("Select if you want to use the EPC we found for your property") - } - } + @Nested + inner class CheckElectricalSafetyAnswersStep { + @Test + fun `Cert uploaded EIC - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } - @Nested - inner class MeesExemptionStepTests { - @Test - fun `User sees a validation error when they do not select a MEES exemption reason`(page: Page) { - val meesExemptionPage = navigator.skipToPropertyRegistrationMeesExemptionPage() + @Test + fun `Cert uploaded EIC - expiry date change link navigates to expiry date page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), + ) + cyaPage.summaryList.expiryDateRow.clickFirstActionLinkAndWait() + assertPageIs(page, ElectricalCertExpiryDateFormPagePropertyRegistration::class) + } - meesExemptionPage.form.submit() + @Test + fun `Cert uploaded EIC - certificate change link navigates to check uploads page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEic(), + ) + cyaPage.summaryList.yourCertificateRow.clickFirstActionLinkAndWait() + assertPageIs(page, CheckElectricalCertUploadsFormPagePropertyRegistration::class) + } - assertPageIs(page, MeesExemptionFormPagePropertyRegistration::class) - assertThat(meesExemptionPage.form.getErrorMessage()) - .containsText("Select the energy efficiency exemption you registered for this property") - } - } + @Test + fun `Cert uploaded EICR - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersUploadedEicr(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } - @Nested - inner class EpcExemptionStepTests { - @Test - fun `User sees a validation error when they do not select an EPC exemption reason`(page: Page) { - val epcExemptionPage = navigator.skipToPropertyRegistrationEpcExemptionPage() + @Test + fun `Provide later - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersProvideLater(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } - epcExemptionPage.form.submit() + @Test + fun `No cert - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersNoCert(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } - assertPageIs(page, EpcExemptionFormPagePropertyRegistration::class) - assertThat(epcExemptionPage.form.getErrorMessage()).isVisible() + @Test + fun `Cert expired - cert type change link navigates to has electrical cert page`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckElectricalSafetyAnswersPage( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckElectricalSafetyAnswersCertExpired(), + ) + cyaPage.summaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } } - } - @Nested - inner class Confirmation { - @Test - fun `Navigating here with an incomplete form returns a 400 error page`(page: Page) { - navigator.navigateToPropertyRegistrationConfirmationPage() - val errorPage = assertPageIs(page, ErrorPage::class) - BaseComponent.assertThat(errorPage.heading).containsText("Sorry, there is a problem with the service") + @Nested + inner class ElectricalCertExpiryDateStepTests { + @ParameterizedTest(name = "{0}") + @Suppress("ktlint:standard:max-line-length") + @MethodSource( + "uk.gov.communities.prsdb.webapp.testHelpers.parameterProviders.AnyDateValidationTestParameterProvider#provideInvalidDateStrings", + ) + fun `Submitting returns a corresponding error when`( + dayMonthYear: Triple, + expectedErrorMessage: String, + ) { + val (day, month, year) = dayMonthYear + val electricalCertExpiryDatePage = navigator.skipToPropertyRegistrationElectricalCertExpiryDatePage() + electricalCertExpiryDatePage.submitDate(day, month, year) + assertThat(electricalCertExpiryDatePage.form.getErrorMessage()).containsText(expectedErrorMessage) + } } - } - - @Nested - inner class PropertyRegistrationStepCheckAnswers { - @Test - fun `After changing an answer, submitting a full section saves the state and returns the CYA page`(page: Page) { - var checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() - - checkAnswersPage.summaryList.ownershipRow.actions.firstActionLink - .clickAndWait() - val ownershipPage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) - - ownershipPage.submitOwnershipType(OwnershipType.LEASEHOLD) - checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - checkAnswersPage.summaryList.licensingRow.actions.firstActionLink - .clickAndWait() - val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) - - licensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) - val licenceNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyRegistration::class) - licenceNumberPage.submitLicenseNumber("licence number") - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - - // Confirmation - verify record saved - val savedJourneyStateCaptor = captor() - verify(savedJourneyStateRepository, times(2)).save(savedJourneyStateCaptor.capture()) - val savedJourneyStateAfterOwnershipUpdate = savedJourneyStateCaptor.allValues[0] - val savedJourneyStateAfterLicensingUpdate = savedJourneyStateCaptor.allValues[1] - assertTrue(savedJourneyStateAfterOwnershipUpdate.serializedState.contains("ownershipType\":\"LEASEHOLD\"")) - assertTrue(savedJourneyStateAfterOwnershipUpdate.serializedState.contains("licensingType\":\"NO_LICENSING\"")) - assertTrue(savedJourneyStateAfterLicensingUpdate.serializedState.contains("licensingType\":\"HMO_ADDITIONAL_LICENCE\"")) - assertTrue(savedJourneyStateAfterLicensingUpdate.serializedState.contains("licenceNumber\":\"licence number\"")) - } - - @Test - fun `the gas supply change link starts a CYA sub-journey that returns to the property registration CYA on submit`(page: Page) { - val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() - checkAnswersPage.complianceSummaryList.gasSupplyRow.clickFirstActionLinkAndWait() - val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) - hasGasSupplyPage.submitHasNoGasSupply() - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - } - - @Test - fun `the electrical certificate change link navigates to the has electrical certificate page`(page: Page) { - val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() - checkAnswersPage.complianceSummaryList.electricalCertRow.clickFirstActionLinkAndWait() - assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) - } - - @Test - fun `the EPC change link takes the user to the confirm epc step if epc is found by uprn`(page: Page) { - whenever(epcRegisterClient.getByUprn(PropertyRegistrationJourneyTests.uprnForSelectedAddress)) - .thenReturn(MockEpcData.createEpcRegisterClientEpcFoundResponse()) - - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersCompliantEpc(), - ) - cyaPage.epcCard - .getAction("Change") - .link - .clickAndWait() - assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) + @Nested + inner class HasEpcStepTests { + @Test + fun `Submitting with the Continue button with no option selected returns an error`(page: Page) { + val hasEpcPage = navigator.skipToPropertyRegistrationHasEpcPage() + hasEpcPage.form.submitPrimaryButton() + assertThat(hasEpcPage.form.getErrorMessage()) + .containsText("Select if you have an EPC for this property") + } } - @Test - fun `the EPC change link takes the user to the has epc step if epc is found by certificate number`(page: Page) { - whenever(epcRegisterClient.getByUprn(PropertyRegistrationJourneyTests.uprnForSelectedAddress)) - .thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) - - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckAnswersEpcFoundByCertificateNumber(), - ) - cyaPage.epcCard - .getAction("Change") - .link - .clickAndWait() - assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + @Nested + inner class FindYourEpcStepTests { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val findYourEpcPage = navigator.skipToPropertyRegistrationFindYourEpcPage() + findYourEpcPage.form.submit() + assertThat(findYourEpcPage.form.getErrorMessage()) + .containsText("Enter a certificate number") + } } - @Test - fun `the licensing number change link navigates to the licensing page`(page: Page) { - val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPageWithSelectiveLicence() - checkAnswersPage.summaryList.licensingNumberRow.clickFirstActionLinkAndWait() - val selectiveLicencePage = assertPageIs(page, SelectiveLicenceFormPagePropertyRegistration::class) - selectiveLicencePage.submitLicenseNumber("SL-99999") - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + @Nested + inner class ConfirmEpcDetailsRetrievedByCertificateNumberStepTests { + @Test + fun `User sees a validation error when they do not select an answer`(page: Page) { + val confirmEpcDetailsPage = + navigator.skipToPropertyRegistrationConfirmEpcDetailsRetrievedByCertificateNumberPage() + confirmEpcDetailsPage.form.submit() + assertThat(confirmEpcDetailsPage.form.getErrorMessage()) + .containsText("Select if you want to use this EPC") + } } - } - @Nested - inner class EpcInDateAtStartOfTenancyCheckStep { - @Test - fun `Submitting with no option selected returns an error`() { - val epcInDateAtStartOfTenancyCheckPage = navigator.skipToPropertyRegistrationEpcInDateAtStartOfTenancyCheckPage() - epcInDateAtStartOfTenancyCheckPage.form.submit() - assertThat(epcInDateAtStartOfTenancyCheckPage.form.getErrorMessage()) - .containsText("Select if the EPC was still in date when the current tenancy began") + @Nested + inner class IsEpcRequiredStepTests { + @Test + fun `Submitting with no option selected returns a validation error`(page: Page) { + val isEpcRequiredPage = navigator.skipToPropertyRegistrationIsEpcRequiredPage() + isEpcRequiredPage.form.submit() + assertThat(isEpcRequiredPage.form.getErrorMessage()) + .containsText("Select if an EPC is required to let this property") + } } - @Test - fun `Page displays the EPC expiry date in the body text and Yes radio hint`() { - val epcInDateAtStartOfTenancyCheckPage = navigator.skipToPropertyRegistrationEpcInDateAtStartOfTenancyCheckPage() - assertThat(epcInDateAtStartOfTenancyCheckPage.bodyParagraph).containsText("5 January 2022") - assertThat(epcInDateAtStartOfTenancyCheckPage.form.yesHint).containsText("5 January 2022") + @Nested + inner class ConfirmEpcDetailsByUprnStepTests { + @Test + fun `User sees a validation error when they do not select an answer`(page: Page) { + val confirmEpcDetailsPage = + navigator.skipToPropertyRegistrationConfirmEpcDetailsByUprnPage() + confirmEpcDetailsPage.form.submit() + assertThat(confirmEpcDetailsPage.form.getErrorMessage()) + .containsText("Select if you want to use the EPC we found for your property") + } } - } - @Nested - inner class HasMeesExemptionStep { - @Test - fun `Submitting with no option selected returns an error`() { - val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() - hasMeesExemptionPage.form.submit() - assertThat(hasMeesExemptionPage.form.getErrorMessage()) - .containsText("Select if you have a registered energy efficiency exemption for this property") - } - } + @Nested + inner class MeesExemptionStepTests { + @Test + fun `User sees a validation error when they do not select a MEES exemption reason`(page: Page) { + val meesExemptionPage = navigator.skipToPropertyRegistrationMeesExemptionPage() - @Nested - inner class EpcMissingStep { - @Test - fun `The page renders the occupied variant for an occupied property`(page: Page) { - val epcMissingPage = navigator.skipToPropertyRegistrationEpcMissingPage(propertyIsOccupied = true) - BaseComponent.assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - BaseComponent.assertThat(epcMissingPage.warning).isVisible() - BaseComponent.assertThat(epcMissingPage.continueAnywayButton).hasText("Continue anyway") - } - - @Test - fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { - val epcMissingPage = navigator.skipToPropertyRegistrationEpcMissingPage(propertyIsOccupied = false) - BaseComponent.assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") - BaseComponent.assertThat(epcMissingPage.warning).isHidden() - BaseComponent.assertThat(epcMissingPage.continueButton).hasText("Continue") - } - } + meesExemptionPage.form.submit() - @Nested - inner class EpcExpiredStep { - @Test - fun `The page renders the occupied variant for an occupied property`(page: Page) { - val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = true) - BaseComponent.assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") - BaseComponent.assertThat(epcExpiredPage.warning).isVisible() - BaseComponent.assertThat(epcExpiredPage.submitButton).hasText("Continue anyway") + assertPageIs(page, MeesExemptionFormPagePropertyRegistration::class) + assertThat(meesExemptionPage.form.getErrorMessage()) + .containsText("Select the energy efficiency exemption you registered for this property") + } } - @Test - fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { - val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = false) - BaseComponent.assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") - BaseComponent.assertThat(epcExpiredPage.warning).isHidden() - BaseComponent.assertThat(epcExpiredPage.submitButton).hasText("Continue") - } + @Nested + inner class EpcExemptionStepTests { + @Test + fun `User sees a validation error when they do not select an EPC exemption reason`(page: Page) { + val epcExemptionPage = navigator.skipToPropertyRegistrationEpcExemptionPage() - @Test - fun `The expiry date is displayed in bold on the occupied variant`(page: Page) { - val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = true) - assertThat(epcExpiredPage.expiryDateParagraph.locator("strong")).hasText("5 January 2022") - } + epcExemptionPage.form.submit() - @Test - fun `The expiry date is displayed in bold on the unoccupied variant`(page: Page) { - val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = false) - assertThat(epcExpiredPage.expiryDateParagraph.locator("strong")).hasText("5 January 2022") + assertPageIs(page, EpcExemptionFormPagePropertyRegistration::class) + assertThat(epcExemptionPage.form.getErrorMessage()).isVisible() + } } - } - @Nested - inner class LowEnergyRatingStep { - @Test - fun `The page renders the occupied variant for an occupied property`(page: Page) { - val lowEnergyRatingPage = navigator.skipToPropertyRegistrationLowEnergyRatingPage(propertyIsOccupied = true) - BaseComponent.assertThat(lowEnergyRatingPage.heading).containsText( - "This property does not meet energy efficiency requirements for letting", - ) - BaseComponent.assertThat(lowEnergyRatingPage.continueAnywayButton).containsText("Continue anyway") + @Nested + inner class Confirmation { + @Test + fun `Navigating here with an incomplete form returns a 400 error page`(page: Page) { + navigator.navigateToPropertyRegistrationConfirmationPage() + val errorPage = assertPageIs(page, ErrorPage::class) + BaseComponent.assertThat(errorPage.heading).containsText("Sorry, there is a problem with the service") + } } - @Test - fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { - val lowEnergyRatingPage = navigator.skipToPropertyRegistrationLowEnergyRatingPage(propertyIsOccupied = false) - BaseComponent.assertThat(lowEnergyRatingPage.heading).containsText( - "You’ll need to get a new EPC before letting this property", - ) - BaseComponent.assertThat(lowEnergyRatingPage.continueButton).containsText("Continue") + @Nested + inner class PropertyRegistrationStepCheckAnswers { + @Test + fun `After changing an answer, submitting a full section saves the state and returns the CYA page`(page: Page) { + var checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() + + checkAnswersPage.summaryList.ownershipRow.actions.firstActionLink + .clickAndWait() + val ownershipPage = assertPageIs(page, OwnershipTypeFormPagePropertyRegistration::class) + + ownershipPage.submitOwnershipType(OwnershipType.LEASEHOLD) + checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + checkAnswersPage.summaryList.licensingRow.actions.firstActionLink + .clickAndWait() + val licensingTypePage = assertPageIs(page, LicensingTypeFormPagePropertyRegistration::class) + + licensingTypePage.submitLicensingType(LicensingType.HMO_ADDITIONAL_LICENCE) + val licenceNumberPage = assertPageIs(page, HmoAdditionalLicenceFormPagePropertyRegistration::class) + licenceNumberPage.submitLicenseNumber("licence number") + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + + // Confirmation - verify record saved + val savedJourneyStateCaptor = captor() + verify(savedJourneyStateRepository, times(2)).save(savedJourneyStateCaptor.capture()) + val savedJourneyStateAfterOwnershipUpdate = savedJourneyStateCaptor.allValues[0] + val savedJourneyStateAfterLicensingUpdate = savedJourneyStateCaptor.allValues[1] + assertTrue(savedJourneyStateAfterOwnershipUpdate.serializedState.contains("ownershipType\":\"LEASEHOLD\"")) + assertTrue(savedJourneyStateAfterOwnershipUpdate.serializedState.contains("licensingType\":\"NO_LICENSING\"")) + assertTrue(savedJourneyStateAfterLicensingUpdate.serializedState.contains("licensingType\":\"HMO_ADDITIONAL_LICENCE\"")) + assertTrue(savedJourneyStateAfterLicensingUpdate.serializedState.contains("licenceNumber\":\"licence number\"")) + } + + @Test + fun `the gas supply change link starts a CYA sub-journey that returns to the property registration CYA on submit`(page: Page) { + val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() + checkAnswersPage.complianceSummaryList.gasSupplyRow.clickFirstActionLinkAndWait() + val hasGasSupplyPage = assertPageIs(page, HasGasSupplyFormPagePropertyRegistration::class) + hasGasSupplyPage.submitHasNoGasSupply() + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + } + + @Test + fun `the electrical certificate change link navigates to the has electrical certificate page`(page: Page) { + val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPage() + checkAnswersPage.complianceSummaryList.electricalCertRow.clickFirstActionLinkAndWait() + assertPageIs(page, HasElectricalCertFormPagePropertyRegistration::class) + } + + @Test + fun `the EPC change link takes the user to the confirm epc step if epc is found by uprn`(page: Page) { + whenever(epcRegisterClient.getByUprn(PropertyRegistrationJourneyTests.uprnForSelectedAddress)) + .thenReturn(MockEpcData.createEpcRegisterClientEpcFoundResponse()) + + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersCompliantEpc(), + ) + + cyaPage.epcCard + .getAction("Change") + .link + .clickAndWait() + assertPageIs(page, ConfirmEpcDetailsRetrievedByUprnFormPagePropertyRegistration::class) + } + + @Test + fun `the EPC change link takes the user to the has epc step if epc is found by certificate number`(page: Page) { + whenever(epcRegisterClient.getByUprn(PropertyRegistrationJourneyTests.uprnForSelectedAddress)) + .thenReturn(MockEpcData.epcRegisterClientEpcNotFoundResponse) + + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckAnswersEpcFoundByCertificateNumber(), + ) + cyaPage.epcCard + .getAction("Change") + .link + .clickAndWait() + assertPageIs(page, HasEpcFormPagePropertyRegistration::class) + } + + @Test + fun `the licensing number change link navigates to the licensing page`(page: Page) { + val checkAnswersPage = navigator.skipToPropertyRegistrationCheckAnswersPageWithSelectiveLicence() + checkAnswersPage.summaryList.licensingNumberRow.clickFirstActionLinkAndWait() + val selectiveLicencePage = assertPageIs(page, SelectiveLicenceFormPagePropertyRegistration::class) + selectiveLicencePage.submitLicenseNumber("SL-99999") + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + } } - } - @Nested - inner class ProvideEpcLaterStep { - @Test - fun `The page renders the occupied variant for an occupied property`(page: Page) { - val provideEpcLaterPage = navigator.skipToPropertyRegistrationProvideEpcLaterPage(propertyIsOccupied = true) - BaseComponent.assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") - BaseComponent.assertThat(provideEpcLaterPage.insetText).containsText( - "To keep the property registered, we need all its compliance certificates within 28 days.", - ) + @Nested + inner class EpcInDateAtStartOfTenancyCheckStep { + @Test + fun `Submitting with no option selected returns an error`() { + val epcInDateAtStartOfTenancyCheckPage = navigator.skipToPropertyRegistrationEpcInDateAtStartOfTenancyCheckPage() + epcInDateAtStartOfTenancyCheckPage.form.submit() + assertThat(epcInDateAtStartOfTenancyCheckPage.form.getErrorMessage()) + .containsText("Select if the EPC was still in date when the current tenancy began") + } + + @Test + fun `Page displays the EPC expiry date in the body text and Yes radio hint`() { + val epcInDateAtStartOfTenancyCheckPage = navigator.skipToPropertyRegistrationEpcInDateAtStartOfTenancyCheckPage() + assertThat(epcInDateAtStartOfTenancyCheckPage.bodyParagraph).containsText("5 January 2022") + assertThat(epcInDateAtStartOfTenancyCheckPage.form.yesHint).containsText("5 January 2022") + } } - @Test - fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { - val provideEpcLaterPage = navigator.skipToPropertyRegistrationProvideEpcLaterPage(propertyIsOccupied = false) - BaseComponent.assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") - BaseComponent.assertThat(provideEpcLaterPage.insetText).isHidden() + @Nested + inner class HasMeesExemptionStep { + @Test + fun `Submitting with no option selected returns an error`() { + val hasMeesExemptionPage = navigator.skipToPropertyRegistrationHasMeesExemptionPage() + hasMeesExemptionPage.form.submit() + assertThat(hasMeesExemptionPage.form.getErrorMessage()) + .containsText("Select if you have a registered energy efficiency exemption for this property") + } } - } - @Nested - inner class CheckEpcAnswersStep { - @Test - fun `Shows EPC card with meets requirements inset for a compliant unexpired EPC`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersCompliantEpc(), - ) + @Nested + inner class EpcMissingStep { + @Test + fun `The page renders the occupied variant for an occupied property`(page: Page) { + val epcMissingPage = navigator.skipToPropertyRegistrationEpcMissingPage(propertyIsOccupied = true) + BaseComponent.assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + BaseComponent.assertThat(epcMissingPage.warning).isVisible() + BaseComponent.assertThat(epcMissingPage.continueAnywayButton).hasText("Continue anyway") + } - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isVisible() - assertThat(cyaPage.epcExpiredText).isHidden() - assertThat(cyaPage.lowRatingText).isHidden() - assertThat(cyaPage.lowRatingOccupiedInset).isHidden() - assertThat(cyaPage.occupiedNoEpcInset).isHidden() + @Test + fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { + val epcMissingPage = navigator.skipToPropertyRegistrationEpcMissingPage(propertyIsOccupied = false) + BaseComponent.assertThat(epcMissingPage.heading).containsText("Your property is missing an EPC") + BaseComponent.assertThat(epcMissingPage.warning).isHidden() + BaseComponent.assertThat(epcMissingPage.continueButton).hasText("Continue") + } } - @Test - fun `Shows EPC card and MEES exemption rows for an unexpired EPC with low rating and exemption`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingWithExemption(), - ) + @Nested + inner class EpcExpiredStep { + @Test + fun `The page renders the occupied variant for an occupied property`(page: Page) { + val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = true) + BaseComponent.assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") + BaseComponent.assertThat(epcExpiredPage.warning).isVisible() + BaseComponent.assertThat(epcExpiredPage.submitButton).hasText("Continue anyway") + } - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.lowRatingText).isVisible() - assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("Yes") - assertThat(cyaPage.rows.meesExemptionRow.value).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - assertThat(cyaPage.lowRatingOccupiedInset).isHidden() - } + @Test + fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { + val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = false) + BaseComponent.assertThat(epcExpiredPage.heading).containsText("This property’s EPC has expired") + BaseComponent.assertThat(epcExpiredPage.warning).isHidden() + BaseComponent.assertThat(epcExpiredPage.submitButton).hasText("Continue") + } - @Test - fun `Shows EPC card, expired text, tenancy check row, and meets requirements inset for expired but valid EPC`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcInDateAtTenancyStart(), - ) + @Test + fun `The expiry date is displayed in bold on the occupied variant`(page: Page) { + val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = true) + assertThat(epcExpiredPage.expiryDateParagraph.locator("strong")).hasText("5 January 2022") + } - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.epcExpiredText).isVisible() - assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") - assertThat(cyaPage.meetsRequirementsInset).isVisible() - assertThat(cyaPage.lowRatingText).isHidden() + @Test + fun `The expiry date is displayed in bold on the unoccupied variant`(page: Page) { + val epcExpiredPage = navigator.skipToPropertyRegistrationEpcExpiredPage(propertyIsOccupied = false) + assertThat(epcExpiredPage.expiryDateParagraph.locator("strong")).hasText("5 January 2022") + } } - @Test - fun `Shows EPC card, expired text, tenancy check, low rating text, and MEES rows for expired EPC with low rating and exemption`( - page: Page, - ) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcLowRatingWithExemption(), + @Nested + inner class LowEnergyRatingStep { + @Test + fun `The page renders the occupied variant for an occupied property`(page: Page) { + val lowEnergyRatingPage = navigator.skipToPropertyRegistrationLowEnergyRatingPage(propertyIsOccupied = true) + BaseComponent.assertThat(lowEnergyRatingPage.heading).containsText( + "This property does not meet energy efficiency requirements for letting", ) + BaseComponent.assertThat(lowEnergyRatingPage.continueAnywayButton).containsText("Continue anyway") + } - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.epcExpiredText).isVisible() - assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") - assertThat(cyaPage.lowRatingText).isVisible() - assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("Yes") - assertThat(cyaPage.rows.meesExemptionRow.value).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isHidden() + @Test + fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { + val lowEnergyRatingPage = navigator.skipToPropertyRegistrationLowEnergyRatingPage(propertyIsOccupied = false) + BaseComponent.assertThat(lowEnergyRatingPage.heading).containsText( + "You’ll need to get a new EPC before letting this property", + ) + BaseComponent.assertThat(lowEnergyRatingPage.continueButton).containsText("Continue") + } } - @Test - fun `Shows hasEpc row with occupied provide-later text for occupied property choosing to provide EPC later`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersProvideLaterOccupied(), + @Nested + inner class ProvideEpcLaterStep { + @Test + fun `The page renders the occupied variant for an occupied property`(page: Page) { + val provideEpcLaterPage = navigator.skipToPropertyRegistrationProvideEpcLaterPage(propertyIsOccupied = true) + BaseComponent.assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") + BaseComponent.assertThat(provideEpcLaterPage.insetText).containsText( + "To keep the property registered, we need all its compliance certificates within 28 days.", ) + } - assertThat(cyaPage.rows.hasEpcRow.value).containsText("Provide EPC details later") - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - assertThat(cyaPage.meetsRequirementsInset).isHidden() + @Test + fun `The page renders the unoccupied variant for an unoccupied property`(page: Page) { + val provideEpcLaterPage = navigator.skipToPropertyRegistrationProvideEpcLaterPage(propertyIsOccupied = false) + BaseComponent.assertThat(provideEpcLaterPage.heading).containsText("Provide your EPC details later") + BaseComponent.assertThat(provideEpcLaterPage.insetText).isHidden() + } } - @Test - fun `Shows hasEpc row with unoccupied provide-later text for unoccupied property choosing to provide EPC later`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersProvideLaterUnoccupied(), - ) + @Nested + inner class CheckEpcAnswersStep { + @Test + fun `Shows EPC card with meets requirements inset for a compliant unexpired EPC`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersCompliantEpc(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isVisible() + assertThat(cyaPage.epcExpiredText).isHidden() + assertThat(cyaPage.lowRatingText).isHidden() + assertThat(cyaPage.lowRatingOccupiedInset).isHidden() + assertThat(cyaPage.occupiedNoEpcInset).isHidden() + } - assertThat(cyaPage.rows.hasEpcRow.value).containsText("within 28 days of the property being occupied") - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - } + @Test + fun `Shows EPC card and MEES exemption rows for an unexpired EPC with low rating and exemption`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingWithExemption(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.lowRatingText).isVisible() + assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("Yes") + assertThat(cyaPage.rows.meesExemptionRow.value).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + assertThat(cyaPage.lowRatingOccupiedInset).isHidden() + } - @Suppress("ktlint:standard:max-line-length") - @Test - fun `Shows EPC card, low rating text, no exemption row, and council inset for occupied property with low rating and no MEES exemption`( - page: Page, - ) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingNoExemptionOccupied(), - ) + @Test + fun `Shows EPC card, expired text, tenancy check row, and meets requirements inset for expired but valid EPC`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcInDateAtTenancyStart(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.epcExpiredText).isVisible() + assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") + assertThat(cyaPage.meetsRequirementsInset).isVisible() + assertThat(cyaPage.lowRatingText).isHidden() + } - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.lowRatingText).isVisible() - assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("No") - assertThat(cyaPage.lowRatingOccupiedInset).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - } + @Test + fun `Shows EPC card, expired text, tenancy check, low rating text, and MEES rows for expired EPC with low rating and exemption`( + page: Page, + ) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcLowRatingWithExemption(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.epcExpiredText).isVisible() + assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") + assertThat(cyaPage.lowRatingText).isVisible() + assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("Yes") + assertThat(cyaPage.rows.meesExemptionRow.value).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + } - @Test - fun `Shows provide EPC later row for unoccupied property with low rating and no MEES exemption`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingNoExemptionUnoccupied(), - ) + @Test + fun `Shows hasEpc row with occupied provide-later text for occupied property choosing to provide EPC later`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersProvideLaterOccupied(), + ) + + assertThat(cyaPage.rows.hasEpcRow.value).containsText("Provide EPC details later") + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + } - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - assertThat(cyaPage.rows.hasEpcRow.value) - .containsText("Provide EPC details later (within 28 days of the property being occupied)") - assertThat(cyaPage.lowRatingText).isHidden() - assertThat(cyaPage.lowRatingOccupiedInset).isHidden() - } + @Test + fun `Shows hasEpc row with unoccupied provide-later text for unoccupied property choosing to provide EPC later`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersProvideLaterUnoccupied(), + ) + + assertThat(cyaPage.rows.hasEpcRow.value).containsText("within 28 days of the property being occupied") + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + } - @Test - fun `Shows hasEpc, isEpcRequired, and exemption reason rows for property with no EPC that is exempt`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersNoEpcExempt(), - ) + @Suppress("ktlint:standard:max-line-length") + @Test + fun `Shows EPC card, low rating text, no exemption row, and council inset for occupied property with low rating and no MEES exemption`( + page: Page, + ) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingNoExemptionOccupied(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.lowRatingText).isVisible() + assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("No") + assertThat(cyaPage.lowRatingOccupiedInset).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + } - assertThat(cyaPage.rows.hasEpcRow.value).containsText("No") - assertThat(cyaPage.rows.isEpcRequiredRow.value).containsText("No") - assertThat(cyaPage.rows.epcExemptionRow.value).isVisible() - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - assertThat(cyaPage.occupiedNoEpcInset).isHidden() - } - - @Suppress("ktlint:standard:max-line-length") - @Test - fun `Shows EPC card, expired text, tenancy check, low rating text, no exemption row, and council inset for occupied property with expired low-rating EPC in date at tenancy start and no exemption`( - page: Page, - ) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcLowRatingNoExemptionOccupied(), - ) + @Test + fun `Shows provide EPC later row for unoccupied property with low rating and no MEES exemption`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersLowRatingNoExemptionUnoccupied(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + assertThat(cyaPage.rows.hasEpcRow.value) + .containsText("Provide EPC details later (within 28 days of the property being occupied)") + assertThat(cyaPage.lowRatingText).isHidden() + assertThat(cyaPage.lowRatingOccupiedInset).isHidden() + } - BaseComponent.assertThat(cyaPage.epcCard).isVisible() - assertThat(cyaPage.epcExpiredText).isVisible() - assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") - assertThat(cyaPage.lowRatingText).isVisible() - assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("No") - assertThat(cyaPage.lowRatingOccupiedInset).isVisible() - assertThat(cyaPage.meetsRequirementsInset).isHidden() - } + @Test + fun `Shows hasEpc, isEpcRequired, and exemption reason rows for property with no EPC that is exempt`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersNoEpcExempt(), + ) + + assertThat(cyaPage.rows.hasEpcRow.value).containsText("No") + assertThat(cyaPage.rows.isEpcRequiredRow.value).containsText("No") + assertThat(cyaPage.rows.epcExemptionRow.value).isVisible() + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + assertThat(cyaPage.occupiedNoEpcInset).isHidden() + } - @Test - fun `Shows hasEpc and isEpcRequired rows with council inset for occupied property with no EPC that is required`(page: Page) { - val cyaPage = - navigator.skipToPropertyRegistrationCheckEpcAnswers( - PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersNoEpcOccupiedNotExempt(), - ) + @Suppress("ktlint:standard:max-line-length") + @Test + fun `Shows EPC card, expired text, tenancy check, low rating text, no exemption row, and council inset for occupied property with expired low-rating EPC in date at tenancy start and no exemption`( + page: Page, + ) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersExpiredEpcLowRatingNoExemptionOccupied(), + ) + + BaseComponent.assertThat(cyaPage.epcCard).isVisible() + assertThat(cyaPage.epcExpiredText).isVisible() + assertThat(cyaPage.rows.tenancyCheckRow.value).containsText("Yes") + assertThat(cyaPage.lowRatingText).isVisible() + assertThat(cyaPage.rows.hasMeesExemptionRow.value).containsText("No") + assertThat(cyaPage.lowRatingOccupiedInset).isVisible() + assertThat(cyaPage.meetsRequirementsInset).isHidden() + } - assertThat(cyaPage.rows.hasEpcRow.value).containsText("No") - assertThat(cyaPage.rows.isEpcRequiredRow.value).containsText("Yes") - assertThat(cyaPage.occupiedNoEpcInset).isVisible() - BaseComponent.assertThat(cyaPage.epcCard).isHidden() - assertThat(cyaPage.rows.epcExemptionRow.key).isHidden() + @Test + fun `Shows hasEpc and isEpcRequired rows with council inset for occupied property with no EPC that is required`(page: Page) { + val cyaPage = + navigator.skipToPropertyRegistrationCheckEpcAnswers( + PropertyStateSessionBuilder.beforePropertyRegistrationCheckEpcAnswersNoEpcOccupiedNotExempt(), + ) + + assertThat(cyaPage.rows.hasEpcRow.value).containsText("No") + assertThat(cyaPage.rows.isEpcRequiredRow.value).containsText("Yes") + assertThat(cyaPage.occupiedNoEpcInset).isVisible() + BaseComponent.assertThat(cyaPage.epcCard).isHidden() + assertThat(cyaPage.rows.epcExemptionRow.key).isHidden() + } } - } - @Nested - inner class ConfirmMissingComplianceStep { - @Test - fun `Submitting with no option selected returns an error`(page: Page) { - val confirmPage = navigator.skipToPropertyRegistrationConfirmMissingCompliancePage() - confirmPage.form.submit() - assertThat(confirmPage.form.getErrorMessage()).containsText("Select whether you want to submit this registration") - } - - @Test - fun `Selecting no, go back redirects to the check answers page`(page: Page) { - val confirmPage = navigator.skipToPropertyRegistrationConfirmMissingCompliancePage() - confirmPage.form.radios.selectValue("false") - confirmPage.form.submit() - assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + @Nested + inner class ConfirmMissingComplianceStep { + @Test + fun `Submitting with no option selected returns an error`(page: Page) { + val confirmPage = navigator.skipToPropertyRegistrationConfirmMissingCompliancePage() + confirmPage.form.submit() + assertThat(confirmPage.form.getErrorMessage()).containsText("Select whether you want to submit this registration") + } + + @Test + fun `Selecting no, go back redirects to the check answers page`(page: Page) { + val confirmPage = navigator.skipToPropertyRegistrationConfirmMissingCompliancePage() + confirmPage.form.radios.selectValue("false") + confirmPage.form.submit() + assertPageIs(page, CheckAnswersPagePropertyRegistration::class) + } } } } From cb45d0c833205fcbea2ac95d718be448de712b19 Mon Sep 17 00:00:00 2001 From: bnjn-mt Date: Fri, 17 Jul 2026 18:04:25 +0100 Subject: [PATCH 06/10] Fixed compile errors --- .../integration/PropertyRegistrationJourneyTests.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt index cd44480b53..4150cdc7d7 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt @@ -1684,23 +1684,23 @@ class PropertyRegistrationJourneyTests : IntegrationTestWithMutableData("data-lo householdsPage.submitNumberOfHouseholds(2) val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) peoplePage.submitNumOfPeople(2) - val bedroomsPage2 = assertPageIs(page, OccupancyNumberOfBedroomsFormPagePropertyRegistration::class) + val bedroomsPage2 = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) bedroomsPage2.submitNumOfBedrooms(3) - val rentIncludesBillsPage = assertPageIs(page, OccupancyRentIncludesBillsFormPagePropertyRegistration::class) + val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) rentIncludesBillsPage.submitIsNotIncluded() - val furnishedPage = assertPageIs(page, OccupancyFurnishedStatusFormPagePropertyRegistration::class) + val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) furnishedPage.submitFurnishedStatus(FurnishedStatus.FURNISHED) - val rentFrequencyPage = assertPageIs(page, OccupancyRentFrequencyFormPagePropertyRegistration::class) + val rentFrequencyPage = assertPageIs(page, RentFrequencyFormPagePropertyRegistration::class) rentFrequencyPage.selectRentFrequency(RentFrequency.MONTHLY) rentFrequencyPage.form.submit() - val rentAmountPage = assertPageIs(page, OccupancyRentAmountFormPagePropertyRegistration::class) + val rentAmountPage = assertPageIs(page, RentAmountFormPagePropertyRegistration::class) rentAmountPage.submitRentAmount("400") taskListPage = assertPageIs(page, TaskListPagePropertyRegistration::class) taskListPage.clickSubmitYourRegistrationTaskWithName("Check and submit your answers") val checkAnswersPage = assertPageIs(page, CheckAnswersPagePropertyRegistration::class) - assertThat(checkAnswersPage.summaryList.licensingTypeRow.value).containsText("Provide this later") + assertThat(checkAnswersPage.summaryList.licensingRow.value).containsText("Provide this later") } @Test From 5ed4a3e1437b7228cd65c4533ae34dc3778d9f96 Mon Sep 17 00:00:00 2001 From: bnjn-mt Date: Fri, 17 Jul 2026 19:35:02 +0100 Subject: [PATCH 07/10] Fix tests --- .../webapp/integration/PropertyRegistrationJourneyTests.kt | 2 -- .../webapp/integration/PropertyRegistrationSinglePageTests.kt | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt index 4150cdc7d7..60b6fec5a6 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationJourneyTests.kt @@ -1684,8 +1684,6 @@ class PropertyRegistrationJourneyTests : IntegrationTestWithMutableData("data-lo householdsPage.submitNumberOfHouseholds(2) val peoplePage = assertPageIs(page, NumberOfPeopleFormPagePropertyRegistration::class) peoplePage.submitNumOfPeople(2) - val bedroomsPage2 = assertPageIs(page, NumberOfBedroomsFormPagePropertyRegistration::class) - bedroomsPage2.submitNumOfBedrooms(3) val rentIncludesBillsPage = assertPageIs(page, RentIncludesBillsFormPagePropertyRegistration::class) rentIncludesBillsPage.submitIsNotIncluded() val furnishedPage = assertPageIs(page, FurnishedStatusFormPagePropertyRegistration::class) diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationSinglePageTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationSinglePageTests.kt index ee228fe96b..1050a7f4de 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationSinglePageTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/integration/PropertyRegistrationSinglePageTests.kt @@ -232,7 +232,7 @@ class PropertyRegistrationSinglePageTests : IntegrationTestWithImmutableData("da @Test fun `Submitting with no licensingType selected returns an error`(page: Page) { val licensingTypePage = navigator.skipToPropertyRegistrationOccupiedLicensingTypePage() - licensingTypePage.form.submit() + licensingTypePage.form.submitPrimaryButton() assertThat(licensingTypePage.form.getErrorMessage()).containsText("Select the type of licensing for the property") } From fddb0d8bf4695aa584cd7765a26c9a2b0ff33a5c Mon Sep 17 00:00:00 2001 From: bnjn-mt Date: Wed, 22 Jul 2026 14:52:43 +0100 Subject: [PATCH 08/10] LicenseService.licenceShouldBeStored method and tests --- .../prsdb/webapp/services/LicenseService.kt | 11 +- .../services/PropertyRegistrationService.kt | 4 +- ...PropertyRegistrationDataStepConfigTests.kt | 50 ++++++++ .../webapp/services/LicenseServiceTests.kt | 32 +++++ .../PropertyRegistrationServiceTests.kt | 115 +++++++++++++++++- 5 files changed, 207 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseService.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseService.kt index ec50f995d1..2543eba87d 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseService.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseService.kt @@ -25,7 +25,7 @@ class LicenseService( updateLicenceType: LicensingType?, updateLicenceNumber: String?, ): License? = - if (updateLicenceType == LicensingType.NO_LICENSING) { + if (!licenceShouldBeStored(updateLicenceType)) { license?.let { licenseRepository.delete(license) } null } else if (license == null) { @@ -36,4 +36,13 @@ class LicenseService( licenseRepository.save(license) license } + + // A licence is only stored when the landlord selects a licence type other than NO_LICENSING and has not opted to + // provide the licensing details later. NO_LICENSING and "provide this later" are both represented by a null licence. + companion object { + fun licenceShouldBeStored( + licenceType: LicensingType?, + licenseProvideLater: Boolean = false, + ): Boolean = licenceType != null && licenceType != LicensingType.NO_LICENSING && !licenseProvideLater + } } diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationService.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationService.kt index fc302d89a3..b344dbe418 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationService.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationService.kt @@ -154,8 +154,8 @@ class PropertyRegistrationService( val address = addressService.findOrCreateAddress(addressModel) val license = - if (licenseType != null) { - licenseService.createLicense(licenseType, licenceNumber) + if (LicenseService.licenceShouldBeStored(licenseType, licenseProvideLater)) { + licenseService.createLicense(licenseType!!, licenceNumber) } else { null } diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfigTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfigTests.kt index 9e34161754..66542481c3 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfigTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfigTests.kt @@ -164,6 +164,56 @@ class SavePropertyRegistrationDataStepConfigTests { ) } + @Test + fun `afterStepIsReached passes licenseProvideLater as true when the user provides licensing later`() { + // Arrange + setupStateForPropertyRegistration() + setupStateForComplianceDataWithNullValues() + whenever(mockState.licensingTypeStep.outcome).thenReturn(LicensingTypeMode.PROVIDE_LATER) + + // Act + stepConfig.afterStepIsReached(mockState) + + // Assert + verify(mockPropertyRegistrationService).registerProperty( + addressModel = any(), + propertyType = any(), + licenseType = anyOrNull(), + licenceNumber = any(), + ownershipType = any(), + isOccupied = any(), + numberOfHouseholds = any(), + numberOfPeople = any(), + baseUserId = any(), + numBedrooms = anyOrNull(), + billsIncludedList = anyOrNull(), + customBillsIncluded = anyOrNull(), + furnishedStatus = anyOrNull(), + rentFrequency = anyOrNull(), + customRentFrequency = anyOrNull(), + rentAmount = anyOrNull(), + customPropertyType = anyOrNull(), + jointLandlordEmails = anyOrNull(), + markedJointLandlord = any(), + hasGasSupply = anyOrNull(), + gasSafetyCertIssueDate = anyOrNull(), + gasSafetyFileUploadIds = any(), + gasSafetyCertProvideLater = anyOrNull(), + electricalSafetyFileUploadIds = any(), + electricalSafetyExpiryDate = anyOrNull(), + electricalCertType = anyOrNull(), + electricalSafetyCertProvideLater = anyOrNull(), + epcCertificateUrl = anyOrNull(), + epcExpiryDate = anyOrNull(), + epcEnergyRating = anyOrNull(), + tenancyStartedBeforeEpcExpiry = anyOrNull(), + epcExemptionReason = anyOrNull(), + epcMeesExemptionReason = anyOrNull(), + epcProvideLater = anyOrNull(), + licenseProvideLater = eq(true), + ) + } + @Test fun `afterStepIsReached sets isAddressAlreadyRegistered when EntityExistsException`() { // Arrange diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseServiceTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseServiceTests.kt index 93efd80f23..383c7cfa84 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseServiceTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseServiceTests.kt @@ -1,6 +1,7 @@ package uk.gov.communities.prsdb.webapp.services import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test @@ -11,6 +12,7 @@ import org.mockito.InjectMocks import org.mockito.Mock import org.mockito.internal.matchers.apachecommons.ReflectionEquals import org.mockito.junit.jupiter.MockitoExtension +import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import uk.gov.communities.prsdb.webapp.constants.enums.LicensingType @@ -78,4 +80,34 @@ class LicenseServiceTests { assertNull(updatedLicence) } + + @Test + fun `updateLicence returns null and does not delete when there is no existing licence and the new licenceType is NO_LICENSING`() { + val updatedLicence = licenseService.updateLicence(null, LicensingType.NO_LICENSING, null) + + verify(mockLicenseRepository, never()).delete(any(License::class.java)) + verify(mockLicenseRepository, never()).save(any(License::class.java)) + + assertNull(updatedLicence) + } + + @Test + fun `licenceShouldBeStored returns true for a licence type other than NO_LICENSING`() { + assertTrue(LicenseService.licenceShouldBeStored(LicensingType.SELECTIVE_LICENCE)) + } + + @Test + fun `licenceShouldBeStored returns false for NO_LICENSING`() { + assertFalse(LicenseService.licenceShouldBeStored(LicensingType.NO_LICENSING)) + } + + @Test + fun `licenceShouldBeStored returns false for a null licence type`() { + assertFalse(LicenseService.licenceShouldBeStored(null)) + } + + @Test + fun `licenceShouldBeStored returns false when the licensing details are being provided later`() { + assertFalse(LicenseService.licenceShouldBeStored(null, licenseProvideLater = true)) + } } diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationServiceTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationServiceTests.kt index 1b5fb7753e..1fb1d2c68b 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationServiceTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationServiceTests.kt @@ -13,6 +13,7 @@ import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.argThat import org.mockito.kotlin.eq +import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import uk.gov.communities.prsdb.webapp.constants.enums.EpcExemptionReason @@ -518,6 +519,7 @@ class PropertyRegistrationServiceTests { customPropertyType, ) + verify(mockLicenseService, never()).createLicense(any(), any()) verify(mockPropertyOwnershipService).createPropertyOwnership( ownershipType = ownershipType, isOccupied = true, @@ -539,6 +541,115 @@ class PropertyRegistrationServiceTests { ) } + @Test + fun `registerProperty does not create a license and sets licenseProvideLater when the user provides licensing later`() { + // Arrange + val ownershipType = OwnershipType.FREEHOLD + val numberOfHouseholds = 1 + val numberOfPeople = 2 + val landlord = MockLandlordData.createLandlord() + val propertyType = PropertyType.DETACHED_HOUSE + val customPropertyType = "End terrace" + val addressDataModel = AddressDataModel("1 Example Road, EG1 2AB") + val address = Address(addressDataModel) + val registrationNumber = RegistrationNumber(RegistrationNumberType.PROPERTY, 1233456) + val numberOfBedrooms = 1 + val billsIncludedList = "Electricity, Water" + val customBillsIncluded = "Internet" + val furnishedStatus = FurnishedStatus.FURNISHED + val rentFrequency = RentFrequency.OTHER + val customRentFrequency = "Fortnightly" + val rentAmount = 123.toBigDecimal() + + val expectedPropertyOwnership = + MockLandlordData.createPropertyOwnership( + ownershipType = ownershipType, + currentNumHouseholds = numberOfHouseholds, + currentNumTenants = numberOfPeople, + landlords = mutableSetOf(landlord), + propertyBuildType = propertyType, + address = address, + license = null, + registrationNumber = registrationNumber, + numberOfBedrooms = numberOfBedrooms, + billsIncludedList = billsIncludedList, + customBillsIncluded = customBillsIncluded, + furnishedStatus = furnishedStatus, + rentFrequency = rentFrequency, + customRentFrequency = customRentFrequency, + rentAmount = rentAmount, + ) + + whenever(mockAddressService.findOrCreateAddress(addressDataModel)).thenReturn(address) + whenever(mockIndividualLandlordRepository.findByBaseUser_Id(landlord.baseUser.id)).thenReturn(landlord) + whenever( + mockPropertyOwnershipService.createPropertyOwnership( + ownershipType = ownershipType, + isOccupied = true, + numberOfHouseholds = numberOfHouseholds, + numberOfPeople = numberOfPeople, + landlords = mutableSetOf(landlord), + propertyBuildType = propertyType, + customPropertyType = customPropertyType, + address = address, + license = null, + numBedrooms = numberOfBedrooms, + billsIncludedList = billsIncludedList, + customBillsIncluded = customBillsIncluded, + furnishedStatus = furnishedStatus, + rentFrequency = rentFrequency, + customRentFrequency = customRentFrequency, + rentAmount = rentAmount, + licenseProvideLater = true, + ), + ).thenReturn(expectedPropertyOwnership) + whenever(mockAbsoluteUrlProvider.buildLandlordDashboardUri()).thenReturn(URI("https:gov.uk")) + + // Act + propertyRegistrationService.registerProperty( + addressDataModel, + propertyType, + null, + "", + ownershipType, + true, + numberOfHouseholds, + numberOfPeople, + landlord.baseUser.id, + numberOfBedrooms, + billsIncludedList, + customBillsIncluded, + furnishedStatus, + rentFrequency, + customRentFrequency, + rentAmount, + customPropertyType, + licenseProvideLater = true, + ) + + // Assert + verify(mockLicenseService, never()).createLicense(any(), any()) + verify(mockPropertyOwnershipService).createPropertyOwnership( + ownershipType = ownershipType, + isOccupied = true, + numberOfHouseholds = numberOfHouseholds, + numberOfPeople = numberOfPeople, + landlords = mutableSetOf(landlord), + propertyBuildType = propertyType, + customPropertyType = customPropertyType, + address = address, + license = null, + numBedrooms = numberOfBedrooms, + billsIncludedList = billsIncludedList, + customBillsIncluded = customBillsIncluded, + furnishedStatus = furnishedStatus, + rentFrequency = rentFrequency, + customRentFrequency = customRentFrequency, + rentAmount = rentAmount, + licenseProvideLater = true, + ) + } + @Test fun `registerProperty sends joint landlord invitation emails when joint landlord emails are provided`() { // Arrange @@ -816,7 +927,7 @@ class PropertyRegistrationServiceTests { rentAmount = anyOrNull(), customPropertyType = anyOrNull(), markedJointLandlord = any(), - licenseProvideLater = any(), + licenseProvideLater = anyOrNull(), ), ).thenReturn(expectedPropertyOwnership) whenever(mockAbsoluteUrlProvider.buildLandlordDashboardUri()).thenReturn(URI("https:gov.uk")) @@ -863,7 +974,7 @@ class PropertyRegistrationServiceTests { rentAmount = anyOrNull(), customPropertyType = anyOrNull(), markedJointLandlord = eq(true), - licenseProvideLater = any(), + licenseProvideLater = anyOrNull(), ) } } From 64c55c47e5d82b7c35a0b8eb519c285200b9349f Mon Sep 17 00:00:00 2001 From: bnjn-mt Date: Wed, 22 Jul 2026 16:14:04 +0100 Subject: [PATCH 09/10] Changed hardcoded provide this later string to a constant in LicensingTypeFormModel --- .../models/requestModels/formModels/LicensingTypeFormModel.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/models/requestModels/formModels/LicensingTypeFormModel.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/models/requestModels/formModels/LicensingTypeFormModel.kt index 9912fb98b0..d48fe3a1fb 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/models/requestModels/formModels/LicensingTypeFormModel.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/models/requestModels/formModels/LicensingTypeFormModel.kt @@ -1,5 +1,6 @@ package uk.gov.communities.prsdb.webapp.models.requestModels.formModels +import uk.gov.communities.prsdb.webapp.constants.PROVIDE_THIS_LATER_BUTTON_ACTION_NAME import uk.gov.communities.prsdb.webapp.constants.enums.LicensingType import uk.gov.communities.prsdb.webapp.database.entity.PropertyOwnership import uk.gov.communities.prsdb.webapp.validation.ConstraintDescriptor @@ -22,7 +23,7 @@ class LicensingTypeFormModel : FormModel { var action: String? = null - fun licensingTypeIsValidForAction(): Boolean = action == "provideThisLater" || licensingType != null + fun licensingTypeIsValidForAction(): Boolean = action == PROVIDE_THIS_LATER_BUTTON_ACTION_NAME || licensingType != null companion object { fun fromPropertyOwnership(propertyOwnership: PropertyOwnership): LicensingTypeFormModel = From b0d8b30910b90dc0475f026e7f612fc3693c0d0e Mon Sep 17 00:00:00 2001 From: bnjn-mt Date: Wed, 29 Jul 2026 16:42:37 +0100 Subject: [PATCH 10/10] Addressed PR comments --- .../prsdb/webapp/constants/enums/LicensingType.kt | 3 ++- .../helpers/converters/MessageKeyConverter.kt | 1 + .../propertyRegistration/states/LicensingState.kt | 11 +++++++++++ .../steps/LicensingTypeStepConfig.kt | 1 + .../steps/SavePropertyRegistrationDataStepConfig.kt | 2 +- .../propertyRegistration/tasks/LicensingTask.kt | 5 +---- .../prsdb/webapp/services/LicenseService.kt | 13 ++++++------- .../webapp/services/PropertyRegistrationService.kt | 4 ++-- src/main/resources/messages/forms.yml | 4 ---- .../SavePropertyRegistrationDataStepConfigTests.kt | 5 ++--- .../prsdb/webapp/services/LicenseServiceTests.kt | 11 +++-------- .../testHelpers/builders/LicensingStateBuilder.kt | 1 + 12 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/constants/enums/LicensingType.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/constants/enums/LicensingType.kt index 80a8308042..ae6104ad46 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/constants/enums/LicensingType.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/constants/enums/LicensingType.kt @@ -5,9 +5,10 @@ enum class LicensingType { HMO_MANDATORY_LICENCE, HMO_ADDITIONAL_LICENCE, NO_LICENSING, + PROVIDE_LATER, ; companion object { - val licencedEntries = entries.minus(NO_LICENSING) + val licencedEntries = entries.minus(NO_LICENSING).minus(PROVIDE_LATER) } } diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/helpers/converters/MessageKeyConverter.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/helpers/converters/MessageKeyConverter.kt index ae01b4a5e4..cf54e25e0f 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/helpers/converters/MessageKeyConverter.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/helpers/converters/MessageKeyConverter.kt @@ -83,6 +83,7 @@ class MessageKeyConverter { LicensingType.HMO_MANDATORY_LICENCE -> "forms.licensingType.radios.option.hmoMandatory.label" LicensingType.HMO_ADDITIONAL_LICENCE -> "forms.licensingType.radios.option.hmoAdditional.label" LicensingType.NO_LICENSING -> "forms.checkPropertyAnswers.propertyDetails.noLicensing" + LicensingType.PROVIDE_LATER -> "forms.checkPropertyAnswers.propertyDetails.licensingProvideLater" } private fun convertOwnershipType(ownershipType: OwnershipType): String = diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/states/LicensingState.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/states/LicensingState.kt index adf5e5a6ba..5b25edd49c 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/states/LicensingState.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/states/LicensingState.kt @@ -4,6 +4,7 @@ import uk.gov.communities.prsdb.webapp.constants.enums.LicensingType import uk.gov.communities.prsdb.webapp.journeys.JourneyState import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.HmoAdditionalLicenceStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.HmoMandatoryLicenceStep +import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.LicensingTypeMode import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.LicensingTypeStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.ProvideLicensingLaterStep import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.SelectiveLicenceStep @@ -28,4 +29,14 @@ interface LicensingState : JourneyState { fun getLicenceNumber(): String = getLicenceNumberOrNull() ?: throw IllegalStateException("Licence number is not available for the current licensing type") + + fun getLicensingType(): LicensingType = + when (val outcome = licensingTypeStep.outcome) { + LicensingTypeMode.SELECTIVE_LICENCE -> LicensingType.SELECTIVE_LICENCE + LicensingTypeMode.HMO_MANDATORY_LICENCE -> LicensingType.HMO_MANDATORY_LICENCE + LicensingTypeMode.HMO_ADDITIONAL_LICENCE -> LicensingType.HMO_ADDITIONAL_LICENCE + LicensingTypeMode.NO_LICENSING -> LicensingType.NO_LICENSING + LicensingTypeMode.PROVIDE_LATER -> LicensingType.PROVIDE_LATER + null -> throw IllegalStateException("Licensing type has not been provided") + } } diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/LicensingTypeStepConfig.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/LicensingTypeStepConfig.kt index f56ddd9123..e3f5e631a4 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/LicensingTypeStepConfig.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/LicensingTypeStepConfig.kt @@ -80,6 +80,7 @@ class LicensingTypeStepConfig( LicensingType.HMO_MANDATORY_LICENCE -> LicensingTypeMode.HMO_MANDATORY_LICENCE LicensingType.HMO_ADDITIONAL_LICENCE -> LicensingTypeMode.HMO_ADDITIONAL_LICENCE LicensingType.NO_LICENSING -> LicensingTypeMode.NO_LICENSING + LicensingType.PROVIDE_LATER -> LicensingTypeMode.PROVIDE_LATER } } } diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfig.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfig.kt index a9d0609643..b4602a8e8c 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfig.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfig.kt @@ -70,7 +70,7 @@ class SavePropertyRegistrationDataStepConfig( } else { null }, - licenseType = state.licensingTypeStep.formModelOrNull?.licensingType, + licenseType = state.getLicensingType(), licenceNumber = state.getLicenceNumberOrNull() ?: "", ownershipType = state.ownershipTypeStep.formModel.notNullValue(OwnershipTypeFormModel::ownershipType), isOccupied = isOccupied, diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/tasks/LicensingTask.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/tasks/LicensingTask.kt index 8170c4e86f..1d69017501 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/tasks/LicensingTask.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/tasks/LicensingTask.kt @@ -1,7 +1,6 @@ package uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.tasks import uk.gov.communities.prsdb.webapp.annotations.webAnnotations.JourneyFrameworkComponent -import uk.gov.communities.prsdb.webapp.config.managers.FeatureFlagManager import uk.gov.communities.prsdb.webapp.journeys.OrParents import uk.gov.communities.prsdb.webapp.journeys.Task import uk.gov.communities.prsdb.webapp.journeys.hasOutcome @@ -15,9 +14,7 @@ import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.Provi import uk.gov.communities.prsdb.webapp.journeys.propertyRegistration.steps.SelectiveLicenceStep @JourneyFrameworkComponent -class LicensingTask( - private val featureFlagManager: FeatureFlagManager, -) : Task() { +class LicensingTask : Task() { override fun makeSubJourney(state: LicensingState) = subJourney(state) { step(journey.licensingTypeStep) { diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseService.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseService.kt index 2543eba87d..3d927aa5d7 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseService.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseService.kt @@ -25,7 +25,7 @@ class LicenseService( updateLicenceType: LicensingType?, updateLicenceNumber: String?, ): License? = - if (!licenceShouldBeStored(updateLicenceType)) { + if (!licenceShouldBeStored(updateLicenceType ?: LicensingType.NO_LICENSING)) { license?.let { licenseRepository.delete(license) } null } else if (license == null) { @@ -37,12 +37,11 @@ class LicenseService( license } - // A licence is only stored when the landlord selects a licence type other than NO_LICENSING and has not opted to - // provide the licensing details later. NO_LICENSING and "provide this later" are both represented by a null licence. + // A licence is only stored when the landlord selects a licence type other than NO_LICENSING or PROVIDE_LATER. + // NO_LICENSING and PROVIDE_LATER are both represented by a null licence, but are distinguished by the + // licenseProvideLater flag on the property ownership. companion object { - fun licenceShouldBeStored( - licenceType: LicensingType?, - licenseProvideLater: Boolean = false, - ): Boolean = licenceType != null && licenceType != LicensingType.NO_LICENSING && !licenseProvideLater + fun licenceShouldBeStored(licenceType: LicensingType): Boolean = + licenceType != LicensingType.NO_LICENSING && licenceType != LicensingType.PROVIDE_LATER } } diff --git a/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationService.kt b/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationService.kt index b344dbe418..05dd62f27b 100644 --- a/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationService.kt +++ b/src/main/kotlin/uk/gov/communities/prsdb/webapp/services/PropertyRegistrationService.kt @@ -154,8 +154,8 @@ class PropertyRegistrationService( val address = addressService.findOrCreateAddress(addressModel) val license = - if (LicenseService.licenceShouldBeStored(licenseType, licenseProvideLater)) { - licenseService.createLicense(licenseType!!, licenceNumber) + if (licenseType != null && LicenseService.licenceShouldBeStored(licenseType)) { + licenseService.createLicense(licenseType, licenceNumber) } else { null } diff --git a/src/main/resources/messages/forms.yml b/src/main/resources/messages/forms.yml index 3a78e37762..3b6d67fdae 100644 --- a/src/main/resources/messages/forms.yml +++ b/src/main/resources/messages/forms.yml @@ -662,10 +662,6 @@ checkPropertyAnswers: licensingType: Licensing type noLicensing: None licensingProvideLater: Provide this later - additionalLandlords: - heading: Additional landlords - interestedParties: - heading: Interested parties tenancyDetails: heading: Tenancy and rental information occupied: Occupied by tenants diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfigTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfigTests.kt index 66542481c3..951c5476cb 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfigTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/journeys/propertyRegistration/steps/SavePropertyRegistrationDataStepConfigTests.kt @@ -36,7 +36,6 @@ import uk.gov.communities.prsdb.webapp.models.dataModels.EpcDataModel import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.EpcExemptionFormModel import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.EpcInDateAtStartOfTenancyCheckFormModel import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.HasJointLandlordsFormModel -import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.LicensingTypeFormModel import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.MeesExemptionReasonFormModel import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.OccupancyFormModel import uk.gov.communities.prsdb.webapp.models.requestModels.formModels.OwnershipTypeFormModel @@ -170,6 +169,7 @@ class SavePropertyRegistrationDataStepConfigTests { setupStateForPropertyRegistration() setupStateForComplianceDataWithNullValues() whenever(mockState.licensingTypeStep.outcome).thenReturn(LicensingTypeMode.PROVIDE_LATER) + whenever(mockState.getLicensingType()).thenReturn(LicensingType.PROVIDE_LATER) // Act stepConfig.afterStepIsReached(mockState) @@ -371,12 +371,11 @@ class SavePropertyRegistrationDataStepConfigTests { whenever(mockPropertyTypeStep.formModel).thenReturn(propertyTypeFormModel) val mockLicensingTypeStep = mock() - val licensingTypeFormModel = LicensingTypeFormModel().apply { licensingType = LicensingType.SELECTIVE_LICENCE } whenever(mockState.licensingTypeStep).thenReturn(mockLicensingTypeStep) - whenever(mockLicensingTypeStep.formModelOrNull).thenReturn(licensingTypeFormModel) whenever(mockLicensingTypeStep.outcome).thenReturn(LicensingTypeMode.SELECTIVE_LICENCE) whenever(mockState.getLicenceNumberOrNull()).thenReturn(null) + whenever(mockState.getLicensingType()).thenReturn(LicensingType.SELECTIVE_LICENCE) val mockOwnershipTypeStep = mock() val ownershipTypeFormModel = OwnershipTypeFormModel().apply { ownershipType = OwnershipType.FREEHOLD } diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseServiceTests.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseServiceTests.kt index 383c7cfa84..7d8dd51ad2 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseServiceTests.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/services/LicenseServiceTests.kt @@ -92,7 +92,7 @@ class LicenseServiceTests { } @Test - fun `licenceShouldBeStored returns true for a licence type other than NO_LICENSING`() { + fun `licenceShouldBeStored returns true for a licence type other than NO_LICENSING or PROVIDE_LATER`() { assertTrue(LicenseService.licenceShouldBeStored(LicensingType.SELECTIVE_LICENCE)) } @@ -102,12 +102,7 @@ class LicenseServiceTests { } @Test - fun `licenceShouldBeStored returns false for a null licence type`() { - assertFalse(LicenseService.licenceShouldBeStored(null)) - } - - @Test - fun `licenceShouldBeStored returns false when the licensing details are being provided later`() { - assertFalse(LicenseService.licenceShouldBeStored(null, licenseProvideLater = true)) + fun `licenceShouldBeStored returns false for PROVIDE_LATER`() { + assertFalse(LicenseService.licenceShouldBeStored(LicensingType.PROVIDE_LATER)) } } diff --git a/src/test/kotlin/uk/gov/communities/prsdb/webapp/testHelpers/builders/LicensingStateBuilder.kt b/src/test/kotlin/uk/gov/communities/prsdb/webapp/testHelpers/builders/LicensingStateBuilder.kt index 32a1d6cb83..f54bb8d26e 100644 --- a/src/test/kotlin/uk/gov/communities/prsdb/webapp/testHelpers/builders/LicensingStateBuilder.kt +++ b/src/test/kotlin/uk/gov/communities/prsdb/webapp/testHelpers/builders/LicensingStateBuilder.kt @@ -34,6 +34,7 @@ interface LicensingStateBuilder> { LicensingType.HMO_MANDATORY_LICENCE -> withLicenceNumber("hmo-mandatory-licence", licenseNumber) LicensingType.HMO_ADDITIONAL_LICENCE -> withLicenceNumber("hmo-additional-licence", licenseNumber) LicensingType.NO_LICENSING -> {} + LicensingType.PROVIDE_LATER -> {} } return self() }