Skip to content

Commit

Permalink
Merge pull request #9 from hmrc/hipp-39
Browse files Browse the repository at this point in the history
HIPP-39: Add Application Name page
  • Loading branch information
PaulCDurham authored Jan 6, 2023
2 parents 4feb920 + efac77c commit 3b58c20
Show file tree
Hide file tree
Showing 20 changed files with 571 additions and 16 deletions.
72 changes: 72 additions & 0 deletions app/controllers/ApplicationNameController.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2023 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 controllers

import controllers.actions._
import forms.ApplicationNameFormProvider
import javax.inject.Inject
import models.Mode
import navigation.Navigator
import pages.ApplicationNamePage
import play.api.i18n.{I18nSupport, MessagesApi}
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import repositories.SessionRepository
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController
import views.html.ApplicationNameView

import scala.concurrent.{ExecutionContext, Future}

class ApplicationNameController @Inject()(
override val messagesApi: MessagesApi,
sessionRepository: SessionRepository,
navigator: Navigator,
identify: IdentifierAction,
getData: DataRetrievalAction,
requireData: DataRequiredAction,
formProvider: ApplicationNameFormProvider,
val controllerComponents: MessagesControllerComponents,
view: ApplicationNameView
)(implicit ec: ExecutionContext) extends FrontendBaseController with I18nSupport {

val form = formProvider()

def onPageLoad(mode: Mode): Action[AnyContent] = (identify andThen getData andThen requireData) {
implicit request =>

val preparedForm = request.userAnswers.get(ApplicationNamePage) match {
case None => form
case Some(value) => form.fill(value)
}

Ok(view(preparedForm, mode))
}

def onSubmit(mode: Mode): Action[AnyContent] = (identify andThen getData andThen requireData).async {
implicit request =>

form.bindFromRequest().fold(
formWithErrors =>
Future.successful(BadRequest(view(formWithErrors, mode))),

value =>
for {
updatedAnswers <- Future.fromTry(request.userAnswers.set(ApplicationNamePage, value))
_ <- sessionRepository.set(updatedAnswers)
} yield Redirect(navigator.nextPage(ApplicationNamePage, mode, updatedAnswers))
)
}
}
17 changes: 15 additions & 2 deletions app/controllers/IndexController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,32 @@

package controllers

import controllers.actions.IdentifierAction
import models.{NormalMode, UserAnswers}
import play.api.i18n.I18nSupport
import play.api.mvc.{Action, AnyContent, MessagesControllerComponents}
import repositories.SessionRepository
import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController
import views.html.IndexView

import javax.inject.Inject
import scala.concurrent.ExecutionContext

class IndexController @Inject()(
val controllerComponents: MessagesControllerComponents,
identify: IdentifierAction,
sessionRepository: SessionRepository,
view: IndexView
) extends FrontendBaseController with I18nSupport {
)(implicit ec: ExecutionContext) extends FrontendBaseController with I18nSupport {

def onPageLoad: Action[AnyContent] = Action { implicit request =>
def onPageLoad: Action[AnyContent] = identify { implicit request =>
Ok(view())
}

def onSubmit: Action[AnyContent] = identify.async { implicit request =>
sessionRepository.set(UserAnswers(request.userId)).map(
_ => Redirect(routes.ApplicationNameController.onPageLoad(NormalMode))
)
}

}
31 changes: 31 additions & 0 deletions app/forms/ApplicationNameFormProvider.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2023 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 forms

import javax.inject.Inject

import forms.mappings.Mappings
import play.api.data.Form

class ApplicationNameFormProvider @Inject() extends Mappings {

def apply(): Form[String] =
Form(
"value" -> text("applicationName.error.required")
.verifying(maxLength(100, "applicationName.error.length"))
)
}
1 change: 1 addition & 0 deletions app/navigation/Navigator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import models._
class Navigator @Inject()() {

private val normalRoutes: Page => UserAnswers => Call = {
case ApplicationNamePage => _ => routes.CheckYourAnswersController.onPageLoad
case _ => _ => routes.IndexController.onPageLoad
}

Expand Down
26 changes: 26 additions & 0 deletions app/pages/ApplicationNamePage.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2023 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 pages

import play.api.libs.json.JsPath

case object ApplicationNamePage extends QuestionPage[String] {

override def path: JsPath = JsPath \ toString

override def toString: String = "applicationName"
}
43 changes: 43 additions & 0 deletions app/viewmodels/checkAnswers/ApplicationNameSummary.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2023 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 viewmodels.checkAnswers

import controllers.routes
import models.{CheckMode, UserAnswers}
import pages.ApplicationNamePage
import play.api.i18n.Messages
import play.twirl.api.HtmlFormat
import uk.gov.hmrc.govukfrontend.views.viewmodels.summarylist.SummaryListRow
import viewmodels.govuk.summarylist._
import viewmodels.implicits._

object ApplicationNameSummary {

def row(answers: UserAnswers)(implicit messages: Messages): Option[SummaryListRow] =
answers.get(ApplicationNamePage).map {
answer =>

SummaryListRowViewModel(
key = "applicationName.checkYourAnswersLabel",
value = ValueViewModel(HtmlFormat.escape(answer).toString),
actions = Seq(
ActionItemViewModel("site.change", routes.ApplicationNameController.onPageLoad(CheckMode).url)
.withVisuallyHiddenText(messages("applicationName.change.hidden"))
)
)
}
}
50 changes: 50 additions & 0 deletions app/views/ApplicationNameView.scala.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@*
* Copyright 2023 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 viewmodels.InputWidth._

@this(
layout: templates.Layout,
formHelper: FormWithCSRF,
govukErrorSummary: GovukErrorSummary,
govukInput: GovukInput,
govukButton: GovukButton
)

@(form: Form[_], mode: Mode)(implicit request: Request[_], messages: Messages)

@layout(pageTitle = title(form, messages("applicationName.title"))) {

@formHelper(action = routes.ApplicationNameController.onSubmit(mode)) {

@if(form.errors.nonEmpty) {
@govukErrorSummary(ErrorSummaryViewModel(form))
}

@govukInput(
InputViewModel(
field = form("value"),
label = LabelViewModel(messages("applicationName.heading")).asPageHeading()
)
.withWidth(Full)
.withHint(HintViewModel(messages("applicationName.hint")))
)

@govukButton(
ButtonViewModel(messages("site.continue"))
)
}
}
15 changes: 9 additions & 6 deletions app/views/IndexView.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
*@

@this(
layout: templates.Layout
layout: templates.Layout,
formHelper: FormWithCSRF,
govukButton: GovukButton
)

@()(implicit request: Request[_], messages: Messages)
Expand All @@ -25,11 +27,12 @@
showBackLink = false
) {

<div align="right">
<a href="/api-hub">Sign In</a>
</div>

<h1 class="govuk-heading-xl">@messages("index.heading")</h1>

<p class="govuk-body">@messages("index.guidance")</p>
@formHelper(action = routes.IndexController.onSubmit) {
@govukButton(
ButtonViewModel(messages("index.registerApplication"))
)
}

}
6 changes: 6 additions & 0 deletions conf/app.routes
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
-> /hmrc-frontend hmrcfrontend.Routes

GET / controllers.IndexController.onPageLoad
POST / controllers.IndexController.onSubmit

GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset)

Expand All @@ -19,3 +20,8 @@ GET /account/sign-out controllers.auth.AuthCo
GET /account/signed-out controllers.auth.SignedOutController.onPageLoad

GET /unauthorised controllers.UnauthorisedController.onPageLoad

GET /applicationName controllers.ApplicationNameController.onPageLoad(mode: Mode = NormalMode)
POST /applicationName controllers.ApplicationNameController.onSubmit(mode: Mode = NormalMode)
GET /changeApplicationName controllers.ApplicationNameController.onPageLoad(mode: Mode = CheckMode)
POST /changeApplicationName controllers.ApplicationNameController.onSubmit(mode: Mode = CheckMode)
2 changes: 1 addition & 1 deletion conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,5 @@ tracking-consent-frontend {
}

features {
welsh-translation: true
welsh-translation: false
}
16 changes: 12 additions & 4 deletions conf/messages.en
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
service.name = api-hub-frontend
service.name = The API Hub

site.back = Back
site.remove = Remove
Expand Down Expand Up @@ -35,9 +35,9 @@ error.number = Please enter a valid number
error.required = Please enter a value
error.summary.title = There is a problem

index.title = api-hub-frontend
index.heading = api-hub-frontend
index.guidance = Welcome to your new frontend. Please see the README file for a guide to getting started.
index.title = Applications
index.heading = Applications
index.registerApplication = Register an application

checkYourAnswers.title = Check Your Answers
checkYourAnswers.heading = Check Your Answers
Expand All @@ -55,3 +55,11 @@ signedOut.guidance = We did not save your answers.

unauthorised.title = You can’t access this service with this account
unauthorised.heading = You can’t access this service with this account

applicationName.title = Application Name
applicationName.heading = What is the name of your application?
applicationName.hint = This name will be used to identify your application to you and your team
applicationName.checkYourAnswersLabel = Application name
applicationName.error.required = Enter an application name
applicationName.error.length = Application name must be 100 characters or less
applicationName.change.hidden = ApplicationName
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
sbt.version=1.6.2
sbt.version=1.7.2
hmrc-frontend-scaffold.version=0.28.0
3 changes: 3 additions & 0 deletions test-utils/generators/PageGenerators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ import org.scalacheck.Arbitrary
import pages._

trait PageGenerators {

implicit lazy val arbitraryApplicationNamePage: Arbitrary[ApplicationNamePage.type] =
Arbitrary(ApplicationNamePage)
}
8 changes: 8 additions & 0 deletions test-utils/generators/UserAnswersEntryGenerators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@ import pages._
import play.api.libs.json.{JsValue, Json}

trait UserAnswersEntryGenerators extends PageGenerators with ModelGenerators {

implicit lazy val arbitraryApplicationNameUserAnswersEntry: Arbitrary[(ApplicationNamePage.type, JsValue)] =
Arbitrary {
for {
page <- arbitrary[ApplicationNamePage.type]
value <- arbitrary[String].suchThat(_.nonEmpty).map(Json.toJson(_))
} yield (page, value)
}
}
3 changes: 2 additions & 1 deletion test-utils/generators/UserAnswersGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ trait UserAnswersGenerator extends TryValues {
self: Generators =>

val generators: Seq[Gen[(QuestionPage[_], JsValue)]] =
arbitrary[(ApplicationNamePage.type, JsValue)] ::
Nil

implicit lazy val arbitraryUserData: Arbitrary[UserAnswers] = {
Expand All @@ -49,4 +50,4 @@ trait UserAnswersGenerator extends TryValues {
)
}
}
}
}
Loading

0 comments on commit 3b58c20

Please sign in to comment.