From f21d1b8a72cdda7c14c7b7daca09f40f0d4dd2e7 Mon Sep 17 00:00:00 2001 From: Jordan Rowe <37838443+jordanrowe@users.noreply.github.com> Date: Tue, 29 Sep 2020 11:28:32 +0100 Subject: [PATCH] [MIBM-88][JR] /value-weight-of-goods (#14) * [MIBM-88][JR] add persistence to /goods-destination and add /value-weight-of-goods --- app/assets/stylesheets/application.scss | 4 +- .../config/AppConfig.scala | 6 + .../GoodsDestinationController.scala | 22 +-- .../ValueWeightOfGoodsController.scala | 67 +++++++++ .../ValueWeightOfGoodsFormProvider.scala | 30 ++++ .../model/declaration/Declaration.scala | 5 +- .../views/ValueWeightOfGoodsView.scala.html | 44 ++++++ .../views/components/phaseBanner.scala.html | 30 ++++ .../layouts/govukFullWidthLayout.scala.html | 19 ++- conf/app.routes | 5 +- conf/application.conf | 4 + conf/messages | 14 +- .../GoodsDestinationControllerSpec.scala | 53 +++++-- .../SkeletonJourneyControllerSpec.scala | 9 -- .../ValueWeightOfGoodsControllerSpec.scala | 135 ++++++++++++++++++ .../ValueWeightOfGoodsFormProviderSpec.scala | 45 ++++++ 16 files changed, 453 insertions(+), 39 deletions(-) create mode 100644 app/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/ValueWeightOfGoodsController.scala create mode 100644 app/uk/gov/hmrc/merchandiseinbaggagefrontend/forms/ValueWeightOfGoodsFormProvider.scala create mode 100644 app/uk/gov/hmrc/merchandiseinbaggagefrontend/views/ValueWeightOfGoodsView.scala.html create mode 100644 app/uk/gov/hmrc/merchandiseinbaggagefrontend/views/components/phaseBanner.scala.html create mode 100644 test/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/ValueWeightOfGoodsControllerSpec.scala create mode 100644 test/uk/gov/hmrc/merchandiseinbaggagefrontend/forms/ValueWeightOfGoodsFormProviderSpec.scala diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 11de4e1d3..37c896af3 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -1,5 +1,5 @@ -$govuk-assets-path: "/merchandise-in-baggage-frontend/assets/lib/govuk-frontend/govuk/assets/"; -$hmrc-assets-path: "/merchandise-in-baggage-frontend/assets/lib/hmrc-frontend/hmrc/"; +$govuk-assets-path: "/merchandise-in-baggage/assets/lib/govuk-frontend/govuk/assets/"; +$hmrc-assets-path: "/merchandise-in-baggage/assets/lib/hmrc-frontend/hmrc/"; @import "lib/govuk-frontend/govuk/all"; @import "lib/hmrc-frontend/hmrc/all"; diff --git a/app/uk/gov/hmrc/merchandiseinbaggagefrontend/config/AppConfig.scala b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/config/AppConfig.scala index 0b7236231..222598360 100644 --- a/app/uk/gov/hmrc/merchandiseinbaggagefrontend/config/AppConfig.scala +++ b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/config/AppConfig.scala @@ -25,6 +25,12 @@ import uk.gov.hmrc.merchandiseinbaggagefrontend.model.core.URL @Singleton class AppConfig() extends PaymentServiceConf with MongoConfiguration { lazy val footerLinkItems: Seq[String] = configSource("footerLinkItems").loadOrThrow[Seq[String]] + + private val serviceIdentifier = "mib" + + private val contactHost = configSource("contact-frontend.host").loadOrThrow[String] + + val betaFeedbackUrl = s"$contactHost/contact/beta-feedback-unauthenticated?service=$serviceIdentifier" } trait PaymentServiceConf { diff --git a/app/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/GoodsDestinationController.scala b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/GoodsDestinationController.scala index 8fdccfe17..a8b0ef074 100644 --- a/app/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/GoodsDestinationController.scala +++ b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/GoodsDestinationController.scala @@ -22,29 +22,35 @@ import play.api.mvc.{Action, AnyContent, MessagesControllerComponents} import uk.gov.hmrc.merchandiseinbaggagefrontend.config.AppConfig import uk.gov.hmrc.merchandiseinbaggagefrontend.forms.GoodsDestinationFormProvider import uk.gov.hmrc.merchandiseinbaggagefrontend.model.core.GoodsDestination +import uk.gov.hmrc.merchandiseinbaggagefrontend.repositories.DeclarationJourneyRepository import uk.gov.hmrc.merchandiseinbaggagefrontend.views.html.GoodsDestinationView -import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController + +import scala.concurrent.{ExecutionContext, Future} @Singleton class GoodsDestinationController @Inject()( override val controllerComponents: MessagesControllerComponents, + actionProvider: DeclarationJourneyActionProvider, formProvider: GoodsDestinationFormProvider, + repo: DeclarationJourneyRepository, view: GoodsDestinationView - )(implicit val appConfig: AppConfig) extends FrontendBaseController { + )(implicit ec: ExecutionContext, appConfig: AppConfig) extends DeclarationJourneyUpdateController { val form: Form[GoodsDestination] = formProvider() - val onPageLoad: Action[AnyContent] = Action { implicit request => - Ok(view(form)) + val onPageLoad: Action[AnyContent] = actionProvider.journeyAction { implicit request => + Ok(view(request.declarationJourney.maybeGoodsDestination.fold(form)(form.fill))) } - //TODO implement once session storage has been done under MIBM-77 - val onSubmit: Action[AnyContent] = Action { implicit request => + val onSubmit: Action[AnyContent] = actionProvider.journeyAction.async { implicit request => form .bindFromRequest() .fold( - formWithErrors => BadRequest(view(formWithErrors)), - value => Redirect(routes.SkeletonJourneyController.valueWeightOfGoods()) + formWithErrors => Future.successful(BadRequest(view(formWithErrors))), + value => + repo.upsert(request.declarationJourney.copy(maybeGoodsDestination = Some(value))).map {_ => + Redirect(routes.ValueWeightOfGoodsController.onPageLoad()) + } ) } diff --git a/app/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/ValueWeightOfGoodsController.scala b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/ValueWeightOfGoodsController.scala new file mode 100644 index 000000000..53665ca05 --- /dev/null +++ b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/ValueWeightOfGoodsController.scala @@ -0,0 +1,67 @@ +/* + * Copyright 2020 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.gov.hmrc.merchandiseinbaggagefrontend.controllers + +import javax.inject.{Inject, Singleton} +import play.api.data.Form +import play.api.mvc.{Action, AnyContent, MessagesControllerComponents} +import uk.gov.hmrc.merchandiseinbaggagefrontend.config.AppConfig +import uk.gov.hmrc.merchandiseinbaggagefrontend.forms.ValueWeightOfGoodsFormProvider +import uk.gov.hmrc.merchandiseinbaggagefrontend.repositories.DeclarationJourneyRepository +import uk.gov.hmrc.merchandiseinbaggagefrontend.views.html.ValueWeightOfGoodsView + +import scala.concurrent.{ExecutionContext, Future} + +@Singleton +class ValueWeightOfGoodsController @Inject()(override val controllerComponents: MessagesControllerComponents, + actionProvider: DeclarationJourneyActionProvider, + formProvider: ValueWeightOfGoodsFormProvider, + repo: DeclarationJourneyRepository, + view: ValueWeightOfGoodsView) + (implicit ec: ExecutionContext, appConfig: AppConfig) + extends DeclarationJourneyUpdateController { + + val form: Form[Boolean] = formProvider() + + val onPageLoad: Action[AnyContent] = actionProvider.journeyAction { implicit request => + request.declarationJourney.maybeGoodsDestination match { + case Some(dest) => Ok( + view(request.declarationJourney.maybeValueWeightOfGoodsExceedsThreshold.fold(form)(form.fill), dest) + ) + case None => Redirect(routes.GoodsDestinationController.onPageLoad()) + } + } + + val onSubmit: Action[AnyContent] = actionProvider.journeyAction.async { implicit request => + request.declarationJourney.maybeGoodsDestination match { + case Some(dest) => + form + .bindFromRequest() + .fold( + formWithErrors => Future successful BadRequest(view(formWithErrors, dest)), + value => { + repo.upsert(request.declarationJourney.copy(maybeValueWeightOfGoodsExceedsThreshold = Some(value))).map { _ => + if (value) Redirect(routes.CannotUseServiceController.onPageLoad()) + else Redirect(routes.SkeletonJourneyController.searchGoods()) + } + } + ) + case None => + Future successful Redirect(routes.GoodsDestinationController.onPageLoad()) + } + } +} diff --git a/app/uk/gov/hmrc/merchandiseinbaggagefrontend/forms/ValueWeightOfGoodsFormProvider.scala b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/forms/ValueWeightOfGoodsFormProvider.scala new file mode 100644 index 000000000..82462d0f1 --- /dev/null +++ b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/forms/ValueWeightOfGoodsFormProvider.scala @@ -0,0 +1,30 @@ +/* + * Copyright 2020 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.gov.hmrc.merchandiseinbaggagefrontend.forms + +import javax.inject.Inject +import play.api.data.Form +import uk.gov.hmrc.merchandiseinbaggagefrontend.forms.mappings.Mappings + +class ValueWeightOfGoodsFormProvider @Inject() extends Mappings { + + def apply(): Form[Boolean] = + Form( + "value" -> boolean("valueWeightOfGoods.error.required") + ) + +} diff --git a/app/uk/gov/hmrc/merchandiseinbaggagefrontend/model/declaration/Declaration.scala b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/model/declaration/Declaration.scala index f809775c8..bb9e08361 100644 --- a/app/uk/gov/hmrc/merchandiseinbaggagefrontend/model/declaration/Declaration.scala +++ b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/model/declaration/Declaration.scala @@ -21,6 +21,7 @@ import java.time.format.DateTimeFormatter import java.util.UUID.randomUUID import play.api.libs.json.{Format, Json, OFormat} +import uk.gov.hmrc.merchandiseinbaggagefrontend.model.core.GoodsDestination import uk.gov.hmrc.merchandiseinbaggagefrontend.utils.ValueClassFormat case class SessionId(value: String) @@ -108,7 +109,9 @@ case class DeclarationJourney(sessionId: SessionId, maybeName: Option[Name] = None, maybeAddress: Option[Address] = None, maybeEori: Option[Eori] = None, - maybeJourneyDetails: Option[JourneyDetails] = None) + maybeJourneyDetails: Option[JourneyDetails] = None, + maybeGoodsDestination: Option[GoodsDestination] = None, + maybeValueWeightOfGoodsExceedsThreshold: Option[Boolean] = None) object DeclarationJourney { implicit val format: OFormat[DeclarationJourney] = Json.format[DeclarationJourney] diff --git a/app/uk/gov/hmrc/merchandiseinbaggagefrontend/views/ValueWeightOfGoodsView.scala.html b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/views/ValueWeightOfGoodsView.scala.html new file mode 100644 index 000000000..c3b5f63b0 --- /dev/null +++ b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/views/ValueWeightOfGoodsView.scala.html @@ -0,0 +1,44 @@ +@* + * Copyright 2020 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *@ + +@import uk.gov.hmrc.govukfrontend.views.html.components +@import uk.gov.hmrc.merchandiseinbaggagefrontend.controllers.routes._ +@import uk.gov.hmrc.merchandiseinbaggagefrontend.model.core.GoodsDestination + +@this( +layout: Layout, +formHelper: FormWithCSRF, +errorSummary: components.errorSummary, +inputYesNo: components.inputYesNo, +button: components.button +) + +@(form: Form[_], dest: GoodsDestination)(implicit request: Request[_], messages: Messages, appConfig: AppConfig) + +@layout(pageTitle = Some(messages(s"valueWeightOfGoods.${dest.toString}.title"))) { + @formHelper(action = ValueWeightOfGoodsController.onSubmit(), 'autoComplete -> "off", 'novalidate -> "novalidate") { + + @errorSummary(form.errors) + + @inputYesNo( + form = form, + legend = messages(s"valueWeightOfGoods.${dest.toString}.heading"), + legendAsHeading = true + ) + + @button("site.continue") + } +} diff --git a/app/uk/gov/hmrc/merchandiseinbaggagefrontend/views/components/phaseBanner.scala.html b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/views/components/phaseBanner.scala.html new file mode 100644 index 000000000..3a3697b99 --- /dev/null +++ b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/views/components/phaseBanner.scala.html @@ -0,0 +1,30 @@ +@* + * Copyright 2020 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *@ + +@this(govukPhaseBanner: GovukPhaseBanner) + +@(phase: String)(implicit messages: Messages, appConfig: AppConfig) + +@feedbackBanner = { +@messages("feedback.before") + @messages("feedback.link") +@messages("feedback.after") +} + +@govukPhaseBanner(PhaseBanner( + tag = Some(Tag(content = Text(phase))), + content = HtmlContent(feedbackBanner) +)) \ No newline at end of file diff --git a/app/uk/gov/hmrc/merchandiseinbaggagefrontend/views/layouts/govukFullWidthLayout.scala.html b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/views/layouts/govukFullWidthLayout.scala.html index fc7cf456d..92ec11fc7 100644 --- a/app/uk/gov/hmrc/merchandiseinbaggagefrontend/views/layouts/govukFullWidthLayout.scala.html +++ b/app/uk/gov/hmrc/merchandiseinbaggagefrontend/views/layouts/govukFullWidthLayout.scala.html @@ -15,12 +15,14 @@ *@ @import uk.gov.hmrc.govukfrontend.views.viewmodels.header.Header +@import uk.gov.hmrc.merchandiseinbaggagefrontend.views.html.components @this( govukTemplate: GovukTemplate, govukHeader: GovukHeader, govukFooter: GovukFooter, -govukBackLink: GovukBackLink +govukBackLink: GovukBackLink, +phaseBanner: components.phaseBanner, ) @( @@ -32,7 +34,7 @@ footerItems: Seq[FooterItem] = Seq.empty, bodyEndBlock: Option[Html] = None, scriptsBlock: Option[Html] = None -)(contentBlock: Html)(implicit messages: Messages) +)(contentBlock: Html)(implicit messages: Messages, appConfig: AppConfig) @headerDefault = { @headerBlock.getOrElse { @@ -44,6 +46,11 @@ } } +@beforeContentDefault = { + @phaseBanner("alpha") + @bodyEndBlock.map(x => x) +} + @footerDefault = { @footerBlock.getOrElse { @govukFooter(new Footer(meta = Some(Meta(items = Some(footerItems))))) @@ -51,8 +58,8 @@ } @bodyEndDefault = { -@bodyEndBlock -@scriptsBlock +@bodyEndBlock.map(x => x) +@scriptsBlock.map(x => x) } @govukTemplate( @@ -60,8 +67,8 @@ pageTitle = pageTitle, headBlock = headBlock, headerBlock = headerDefault, - beforeContentBlock = beforeContentBlock, + beforeContentBlock = Some(beforeContentDefault), footerBlock = footerDefault, mainClasses = Some("govuk-main-wrapper--auto-spacing"), - bodyEndBlock = Some(bodyEndDefault) + bodyEndBlock = Some(bodyEndDefault), )(contentBlock) \ No newline at end of file diff --git a/conf/app.routes b/conf/app.routes index 200c1fa35..5e7929e41 100644 --- a/conf/app.routes +++ b/conf/app.routes @@ -9,7 +9,6 @@ GET /payment uk.gov.hmrc.merchandiseinbaggagefronten GET /process-payment uk.gov.hmrc.merchandiseinbaggagefrontend.controllers.PaymentController.onSubmit() GET /select-declaration-type uk.gov.hmrc.merchandiseinbaggagefrontend.controllers.SkeletonJourneyController.selectDeclarationType -GET /value-weight-of-goods uk.gov.hmrc.merchandiseinbaggagefrontend.controllers.SkeletonJourneyController.valueWeightOfGoods GET /search-goods uk.gov.hmrc.merchandiseinbaggagefrontend.controllers.SkeletonJourneyController.searchGoods GET /search-goods-country uk.gov.hmrc.merchandiseinbaggagefrontend.controllers.SkeletonJourneyController.searchGoodsCountry GET /purchase-details uk.gov.hmrc.merchandiseinbaggagefrontend.controllers.SkeletonJourneyController.purchaseDetails @@ -33,6 +32,10 @@ POST /excise-and-restricted-goods uk.gov.hmrc.merchandiseinbaggagefronten GET /goods-destination uk.gov.hmrc.merchandiseinbaggagefrontend.controllers.GoodsDestinationController.onPageLoad() POST /goods-destination uk.gov.hmrc.merchandiseinbaggagefrontend.controllers.GoodsDestinationController.onSubmit() +# ValueWeightOfGoods +GET /value-weight-of-goods uk.gov.hmrc.merchandiseinbaggagefrontend.controllers.ValueWeightOfGoodsController.onPageLoad() +POST /value-weight-of-goods uk.gov.hmrc.merchandiseinbaggagefrontend.controllers.ValueWeightOfGoodsController.onSubmit() + # CannotUseService GET /cannot-use-service uk.gov.hmrc.merchandiseinbaggagefrontend.controllers.CannotUseServiceController.onPageLoad() diff --git a/conf/application.conf b/conf/application.conf index fc63ffd09..6d9d2d257 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -106,6 +106,10 @@ google-analytics { host = auto } +contact-frontend { + host = "http://localhost:9250" +} + footerLinkItems = ["cookies", "privacy", "termsConditions", "govukHelp"] mongodb { diff --git a/conf/messages b/conf/messages index 560780a19..c84199d44 100644 --- a/conf/messages +++ b/conf/messages @@ -2,6 +2,11 @@ service.name = merchandise-in-baggage-frontend service.homePageUrl = /merchandise-in-baggage-frontend service.text = This is your new service +# Alpha/Beta Banner +feedback.before = This is a new service - your +feedback.link = feedback +feedback.after = will help us to improve it. + footer.cookies.text = Cookies footer.cookies.url = /help/cookies footer.privacy.text = Privacy policy @@ -22,7 +27,6 @@ payment.button = Pay now next.button = Next selectDeclarationType.title = What do you need to declare? -valueWeightOfGoods.title = Is the total value of the goods over £1500 or 1000kg? searchGoods.title = What goods are you bringing into the UK? searchGoodsCountry.title = In what country did you buy the x? purchaseDetails.title = How much did you pay for the x? @@ -81,6 +85,14 @@ goodsDestination.gb = England, Wales or Scotland goodsDestination.error.required = Select one of the options below +# ValueWeightOfGoods +valueWeightOfGoods.ni.title = Is the total value of the goods over £873 or 1000 kilograms (kg)? +valueWeightOfGoods.gb.title = Is the total value of the goods over £1500 or 1000 kilograms (kg)? +valueWeightOfGoods.ni.title = Is the total value of the goods over £873 or 1000 kilograms (kg)? +valueWeightOfGoods.gb.title = Is the total value of the goods over £1500 or 1000 kilograms (kg)? +valueWeightOfGoods.error.required = Select one of the options below + + # CannotUseService cannotUseService.title = You need to submit a full customs declaration cannotUseService.heading = You need to submit a full customs declaration diff --git a/test/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/GoodsDestinationControllerSpec.scala b/test/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/GoodsDestinationControllerSpec.scala index 962f6d235..eecf4cb45 100644 --- a/test/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/GoodsDestinationControllerSpec.scala +++ b/test/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/GoodsDestinationControllerSpec.scala @@ -18,32 +18,61 @@ package uk.gov.hmrc.merchandiseinbaggagefrontend.controllers import play.api.test.Helpers._ import uk.gov.hmrc.merchandiseinbaggagefrontend.forms.GoodsDestinationFormProvider +import uk.gov.hmrc.merchandiseinbaggagefrontend.model.core.GoodsDestination import uk.gov.hmrc.merchandiseinbaggagefrontend.views.html.GoodsDestinationView +import scala.concurrent.ExecutionContext.Implicits.global + class GoodsDestinationControllerSpec extends DeclarationJourneyControllerSpec { private val formProvider = new GoodsDestinationFormProvider() private val form = formProvider() private lazy val view = injector.instanceOf[GoodsDestinationView] - private lazy val controller = new GoodsDestinationController(controllerComponents, formProvider, view) + private lazy val controller = + new GoodsDestinationController( + controllerComponents, actionBuilder, formProvider, declarationJourneyRepository, view) "onPageLoad" must { - "return OK and render the view" in { - val getRequest = buildGet(routes.GoodsDestinationController.onPageLoad().url) - val result = controller.onPageLoad()(getRequest) + val url = routes.GoodsDestinationController.onPageLoad().url + val getRequest = buildGet(url, sessionId) + + behave like anEndpointRequiringASessionIdAndLinkedDeclarationJourneyToLoad(controller, url) + + "return OK and render the view" when { + "a declaration has been started" in { + givenADeclarationJourneyIsPersisted(startedDeclarationJourney) + + val result = controller.onPageLoad()(getRequest) + + status(result) mustEqual OK + contentAsString(result) mustEqual + view(form)(getRequest, messagesApi.preferred(getRequest), appConfig).toString + } + } + + "return OK and render the view" when { + "a declaration has been started and a value saved" in { + givenADeclarationJourneyIsPersisted(startedDeclarationJourney.copy(maybeGoodsDestination = Some(GoodsDestination.values.head))) + + val result = controller.onPageLoad()(getRequest) - status(result) mustEqual OK - contentAsString(result) mustEqual - view(form)(getRequest, messagesApi.preferred(getRequest), appConfig).toString + status(result) mustEqual OK + contentAsString(result) mustEqual + view(form.fill(GoodsDestination.values.head))(getRequest, messagesApi.preferred(getRequest), appConfig).toString + } } } "onSubmit" must { - val postRequest = buildPost(routes.GoodsDestinationController.onSubmit().url) + val url = routes.GoodsDestinationController.onSubmit().url + val postRequest = buildPost(url, sessionId) + + behave like anEndpointRequiringASessionIdAndLinkedDeclarationJourneyToUpdate(controller, url) - //TODO assert against redirection/storage when MIBM-77 done "Redirect to /value-weight-of-goods" when { - "a valid selection submitted" in { + "a declaration is started and a valid selection submitted" in { + givenADeclarationJourneyIsPersisted(startedDeclarationJourney) + val request = postRequest.withFormUrlEncodedBody(("value", "ni")) form.bindFromRequest()(request) @@ -51,12 +80,14 @@ class GoodsDestinationControllerSpec extends DeclarationJourneyControllerSpec { val result = controller.onSubmit()(request) status(result) mustEqual SEE_OTHER - redirectLocation(result).get mustEqual routes.SkeletonJourneyController.valueWeightOfGoods().toString + redirectLocation(result).get mustEqual routes.ValueWeightOfGoodsController.onPageLoad().toString } } "return BAD_REQUEST and errors" when { "no selection is made" in { + givenADeclarationJourneyIsPersisted(startedDeclarationJourney) + val submittedForm = form.bindFromRequest()(postRequest) val result = controller.onSubmit()(postRequest) diff --git a/test/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/SkeletonJourneyControllerSpec.scala b/test/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/SkeletonJourneyControllerSpec.scala index 88a4bc708..708a97776 100644 --- a/test/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/SkeletonJourneyControllerSpec.scala +++ b/test/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/SkeletonJourneyControllerSpec.scala @@ -33,15 +33,6 @@ class SkeletonJourneyControllerSpec extends DeclarationJourneyControllerSpec { } } - "valueWeightOfGoods" should { - "render the page" in { - val title = "Is the total value of the goods over £1500 or 1000kg?" - val getRequest = buildGet(routes.SkeletonJourneyController.valueWeightOfGoods().url) - - ensure(controller.valueWeightOfGoods(getRequest), title, routes.SkeletonJourneyController.searchGoods()) - } - } - "searchGoods" should { "render the page" in { val title = "What goods are you bringing into the UK?" diff --git a/test/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/ValueWeightOfGoodsControllerSpec.scala b/test/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/ValueWeightOfGoodsControllerSpec.scala new file mode 100644 index 000000000..2940d1335 --- /dev/null +++ b/test/uk/gov/hmrc/merchandiseinbaggagefrontend/controllers/ValueWeightOfGoodsControllerSpec.scala @@ -0,0 +1,135 @@ +/* + * Copyright 2020 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.gov.hmrc.merchandiseinbaggagefrontend.controllers + +import play.api.test.Helpers._ +import uk.gov.hmrc.merchandiseinbaggagefrontend.forms.ValueWeightOfGoodsFormProvider +import uk.gov.hmrc.merchandiseinbaggagefrontend.model.core.GoodsDestination._ +import uk.gov.hmrc.merchandiseinbaggagefrontend.views.html.ValueWeightOfGoodsView + +import scala.concurrent.ExecutionContext.Implicits.global + +class ValueWeightOfGoodsControllerSpec extends DeclarationJourneyControllerSpec { + private val formProvider = new ValueWeightOfGoodsFormProvider() + private val form = formProvider() + + private lazy val view = injector.instanceOf[ValueWeightOfGoodsView] + + private lazy val controller = + new ValueWeightOfGoodsController( + controllerComponents, actionBuilder, formProvider, declarationJourneyRepository, view) + + "onPageLoad" must { + val url = routes.ValueWeightOfGoodsController.onPageLoad().url + val request = buildGet(url, sessionId) + + behave like anEndpointRequiringASessionIdAndLinkedDeclarationJourneyToLoad(controller, url) + + "redirect to /goods-destination" when { + "a declaration has been started but a required answer is missing in the journey" in { + givenADeclarationJourneyIsPersisted(startedDeclarationJourney) + + val result = controller.onPageLoad()(request) + + status(result) mustEqual SEE_OTHER + redirectLocation(result).get mustEqual routes.GoodsDestinationController.onPageLoad().toString + } + } + + "return OK and render the view" when { + "a declaration has been started with a destination of Northern Ireland" in { + givenADeclarationJourneyIsPersisted(startedDeclarationJourney.copy(maybeGoodsDestination = Some(NorthernIreland))) + + val result = controller.onPageLoad()(request) + + status(result) mustEqual OK + contentAsString(result) mustEqual + view(form, NorthernIreland)(request, messagesApi.preferred(request), appConfig).toString + } + + "a declaration has been started with a destination of England, Wales or Scotland" in { + givenADeclarationJourneyIsPersisted(startedDeclarationJourney.copy(maybeGoodsDestination = Some(EngScoWal))) + + val result = controller.onPageLoad()(request) + + status(result) mustEqual OK + contentAsString(result) mustEqual + view(form, EngScoWal)(request, messagesApi.preferred(request), appConfig).toString + } + + "a declaration has been started and a value saved" in { + givenADeclarationJourneyIsPersisted(startedDeclarationJourney + .copy( + maybeGoodsDestination = Some(NorthernIreland), + maybeValueWeightOfGoodsExceedsThreshold = Some(true))) + + val result = controller.onPageLoad()(request) + + status(result) mustEqual OK + contentAsString(result) mustEqual + view(form.fill(true), NorthernIreland)(request, messagesApi.preferred(request), appConfig).toString + } + } + } + + "onSubmit" must { + val url = routes.ValueWeightOfGoodsController.onSubmit().url + val postRequest = buildPost(url, sessionId) + + behave like anEndpointRequiringASessionIdAndLinkedDeclarationJourneyToUpdate(controller, url) + + "Redirect to /search-goods" when { + "a declaration is started and false is submitted" in { + givenADeclarationJourneyIsPersisted(startedDeclarationJourney.copy(maybeGoodsDestination = Some(NorthernIreland))) + + val request = postRequest.withFormUrlEncodedBody(("value", "false")) + val result = controller.onSubmit()(request) + + status(result) mustEqual SEE_OTHER + redirectLocation(result).get mustEqual routes.SkeletonJourneyController.searchGoods().toString + + startedDeclarationJourney.maybeValueWeightOfGoodsExceedsThreshold mustBe None + declarationJourneyRepository.findBySessionId(sessionId).futureValue.get.maybeValueWeightOfGoodsExceedsThreshold mustBe Some(false) + } + } + + "Redirect to /cannot-use-service" when { + "a declaration is started and true is submitted" in { + givenADeclarationJourneyIsPersisted(startedDeclarationJourney.copy(maybeGoodsDestination = Some(NorthernIreland))) + + val request = postRequest.withFormUrlEncodedBody(("value", "true")) + val result = controller.onSubmit()(request) + + status(result) mustEqual SEE_OTHER + redirectLocation(result).get mustEqual routes.CannotUseServiceController.onPageLoad().toString + } + } + + "return BAD_REQUEST and errors" when { + "no selection is made" in { + givenADeclarationJourneyIsPersisted(startedDeclarationJourney.copy(maybeGoodsDestination = Some(NorthernIreland))) + + val submittedForm = form.bindFromRequest()(postRequest) + val result = controller.onSubmit()(postRequest) + + status(result) mustEqual BAD_REQUEST + contentAsString(result) mustEqual + view(submittedForm, NorthernIreland)(postRequest, messagesApi.preferred(postRequest), appConfig).toString + } + } + } +} diff --git a/test/uk/gov/hmrc/merchandiseinbaggagefrontend/forms/ValueWeightOfGoodsFormProviderSpec.scala b/test/uk/gov/hmrc/merchandiseinbaggagefrontend/forms/ValueWeightOfGoodsFormProviderSpec.scala new file mode 100644 index 000000000..51de9dda9 --- /dev/null +++ b/test/uk/gov/hmrc/merchandiseinbaggagefrontend/forms/ValueWeightOfGoodsFormProviderSpec.scala @@ -0,0 +1,45 @@ +/* + * Copyright 2020 HM Revenue & Customs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package uk.gov.hmrc.merchandiseinbaggagefrontend.forms + +import play.api.data.FormError +import uk.gov.hmrc.merchandiseinbaggagefrontend.forms.behaviours.BooleanFieldBehaviours + +class ValueWeightOfGoodsFormProviderSpec extends BooleanFieldBehaviours { + + val requiredKey = "valueWeightOfGoods.error.required" + val invalidKey = "error.boolean" + + val form = new ValueWeightOfGoodsFormProvider()() + + ".value" must { + + val fieldName = "value" + + behave like booleanField( + form, + fieldName, + invalidError = FormError(fieldName, invalidKey) + ) + + behave like mandatoryField( + form, + fieldName, + requiredError = FormError(fieldName, requiredKey) + ) + } +}