diff --git a/README.md b/README.md index 06639f1..0a7efb9 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ This should start this service and any dependent services. Once the script has finished, the service will be available on http://localhost:9618/api-test-user +For CTC users, the service will be available on http://localhost:9618/api-test-user/create +http://localhost:9485/manage-transit-movements/what-do-you-want-to-do + ## Running tests diff --git a/app/uk/gov/hmrc/testuser/config/ApplicationConfig.scala b/app/uk/gov/hmrc/testuser/config/ApplicationConfig.scala index 56d73d0..b897a92 100644 --- a/app/uk/gov/hmrc/testuser/config/ApplicationConfig.scala +++ b/app/uk/gov/hmrc/testuser/config/ApplicationConfig.scala @@ -26,10 +26,12 @@ class ApplicationConfig @Inject() (config: Configuration) { private lazy val urlFooterConfig = config.underlying.getConfig("urls.footer") private lazy val feedbackSurveyConfig = config.underlying.getConfig("feedbackBanner.generic") - lazy val cookies: String = urlFooterConfig.getString("cookies") - lazy val privacy: String = urlFooterConfig.getString("privacy") - lazy val termsConditions: String = urlFooterConfig.getString("termsConditions") - lazy val govukHelp: String = urlFooterConfig.getString("govukHelp") - lazy val accessibility: String = urlFooterConfig.getString("accessibility") - lazy val feedbackSurveyUrl = feedbackSurveyConfig.getString("surveyUrl") + lazy val cookies: String = urlFooterConfig.getString("cookies") + lazy val privacy: String = urlFooterConfig.getString("privacy") + lazy val termsConditions: String = urlFooterConfig.getString("termsConditions") + lazy val govukHelp: String = urlFooterConfig.getString("govukHelp") + lazy val accessibility: String = urlFooterConfig.getString("accessibility") + lazy val feedbackSurveyUrl = feedbackSurveyConfig.getString("surveyUrl") + lazy val routingLoginUrls = config.get[Seq[String]]("routing-login-urls") + lazy val serviceKeys = config.get[Seq[String]]("services") } diff --git a/app/uk/gov/hmrc/testuser/controllers/TestUserController.scala b/app/uk/gov/hmrc/testuser/controllers/TestUserController.scala index 3501080..5259116 100644 --- a/app/uk/gov/hmrc/testuser/controllers/TestUserController.scala +++ b/app/uk/gov/hmrc/testuser/controllers/TestUserController.scala @@ -32,26 +32,32 @@ import uk.gov.hmrc.testuser.config.ApplicationConfig import uk.gov.hmrc.testuser.connectors.ApiPlatformTestUserConnector import uk.gov.hmrc.testuser.models.{NavLink, UserTypes} import uk.gov.hmrc.testuser.services.{NavigationService, TestUserService} -import uk.gov.hmrc.testuser.views.html.{CreateTestUserView, TestUserView} +import uk.gov.hmrc.testuser.views.html.{CreateTestUserView, CreateTestUserViewGeneric, TestUserView, TestUserViewGeneric} class TestUserController @Inject() ( - override val messagesApi: MessagesApi, - testUserService: TestUserService, - navigationService: NavigationService, - apiPlatformTestUserConnector: ApiPlatformTestUserConnector, - messagesControllerComponents: MessagesControllerComponents, - createTestUser: CreateTestUserView, - testUser: TestUserView -)(implicit val ec: ExecutionContext, config: ApplicationConfig) - extends FrontendController(messagesControllerComponents) - with I18nSupport - with ApplicationLogger - with WithUnsafeDefaultFormBinding { + override val messagesApi: MessagesApi, + testUserService: TestUserService, + navigationService: NavigationService, + apiPlatformTestUserConnector: ApiPlatformTestUserConnector, + messagesControllerComponents: MessagesControllerComponents, + createTestUser: CreateTestUserView, + createTestUserGeneric: CreateTestUserViewGeneric, + testUser: TestUserView, + testUserGeneric: TestUserViewGeneric + )(implicit val ec: ExecutionContext, + config: ApplicationConfig + ) extends FrontendController(messagesControllerComponents) with I18nSupport with ApplicationLogger with WithUnsafeDefaultFormBinding { def showCreateUserPage() = headerNavigation { implicit request => navLinks => Future.successful(Ok(createTestUser(navLinks, CreateUserForm.form))) } + def showCreateUserPageGeneric() = headerNavigation { implicit request =>navLinks => + testUserService.services.flatMap(services => + Future.successful(Ok(createTestUserGeneric(services.filter(s => config.serviceKeys.contains(s.key)), navLinks, CreateUserForm.form))) + ) + } + def createUser() = headerNavigation { implicit request => navLinks => def validForm(form: CreateUserForm) = { UserTypes.from(form.userType.getOrElse("")) match { @@ -66,6 +72,26 @@ class TestUserController @Inject() ( CreateUserForm.form.bindFromRequest().fold(invalidForm, validForm) } + def createUserGeneric() = headerNavigation { implicit request =>navLinks => + def validForm(form: CreateUserForm) = { + val x = UserTypes.from(form.userType.getOrElse("")) + val y = form.services + + (x, y) match { + case (Some(uType), Some(services)) => + testUserService.createUserGeneric(uType, services.split(",").toSeq) map (user => Ok(testUserGeneric(navLinks, user))) + case _ => Future.failed(new BadRequestException("Invalid request")) + } + } + + def invalidForm(invalidForm: Form[CreateUserForm]) = { + testUserService.services.flatMap(services => + Future.successful(BadRequest(createTestUserGeneric(services.filter(s => config.serviceKeys.contains(s.key)), navLinks, invalidForm))) + ) + } + + CreateUserForm.form.bindFromRequest().fold(invalidForm, validForm) + } private def headerNavigation(f: Request[AnyContent] => Seq[NavLink] => Future[Result]): Action[AnyContent] = { Action.async { implicit request => @@ -81,13 +107,14 @@ class TestUserController @Inject() ( } } -case class CreateUserForm(userType: Option[String]) +case class CreateUserForm(userType: Option[String], services: Option[String]) object CreateUserForm { val form: Form[CreateUserForm] = Form( mapping( - "userType" -> optional(text).verifying(FormKeys.createUserTypeNoChoiceKey, s => s.isDefined) + "userType" -> optional(text).verifying(FormKeys.createUserTypeNoChoiceKey, userType => userType.isDefined), + "serviceSelection" -> optional(text).verifying(FormKeys.createServicesNoChoiceKey, selectedServices => selectedServices.isDefined), )(CreateUserForm.apply)(CreateUserForm.unapply) ) } diff --git a/app/uk/gov/hmrc/testuser/controllers/controllers.scala b/app/uk/gov/hmrc/testuser/controllers/controllers.scala index 780c419..5b197e3 100644 --- a/app/uk/gov/hmrc/testuser/controllers/controllers.scala +++ b/app/uk/gov/hmrc/testuser/controllers/controllers.scala @@ -20,5 +20,6 @@ package object controllers { object FormKeys { val createUserTypeNoChoiceKey = "create.user.type.no.choice.field" + val createServicesNoChoiceKey = "create.user.services.no.choice.field" } } diff --git a/app/uk/gov/hmrc/testuser/models/FieldDefinitionsProvider.scala b/app/uk/gov/hmrc/testuser/models/FieldDefinitionsProvider.scala index 431bb99..8bd9d3e 100644 --- a/app/uk/gov/hmrc/testuser/models/FieldDefinitionsProvider.scala +++ b/app/uk/gov/hmrc/testuser/models/FieldDefinitionsProvider.scala @@ -42,4 +42,13 @@ object FieldDefinitions { FieldDefinition("individualDetails", "Individual Details", Seq()), FieldDefinition("groupIdentifier", "Group Identifier", Seq(INDIVIDUAL, ORGANISATION)) ) + + def getCtc(): Seq[FieldDefinition] = Seq( + FieldDefinition("eoriNumber", "Economic Operator Registration and Identification (EORI) number", Seq(INDIVIDUAL, ORGANISATION)), + FieldDefinition("userFullName", "Full Name", Seq(INDIVIDUAL, ORGANISATION)), + FieldDefinition("emailAddress", "Email Address", Seq(INDIVIDUAL, ORGANISATION)), + FieldDefinition("organisationDetails", "Organisation Details", Seq(ORGANISATION)), + FieldDefinition("individualDetails", "Individual Details", Seq(INDIVIDUAL)), + FieldDefinition("groupIdentifier", "Group Identifier", Seq(INDIVIDUAL, ORGANISATION)) + ) } diff --git a/app/uk/gov/hmrc/testuser/services/TestUserService.scala b/app/uk/gov/hmrc/testuser/services/TestUserService.scala index 7523dc5..20ce60a 100644 --- a/app/uk/gov/hmrc/testuser/services/TestUserService.scala +++ b/app/uk/gov/hmrc/testuser/services/TestUserService.scala @@ -27,12 +27,22 @@ import uk.gov.hmrc.testuser.models.{Service, TestUser, UserTypes} class TestUserService @Inject() (apiPlatformTestUserConnector: ApiPlatformTestUserConnector)(implicit ec: ExecutionContext) { + def services(implicit hc: HeaderCarrier) = apiPlatformTestUserConnector.getServices() + def createUser(userType: UserType)(implicit hc: HeaderCarrier): Future[TestUser] = { for { services <- apiPlatformTestUserConnector.getServices() testUser <- createUserWithServices(userType, services) } yield testUser + } + def createUserGeneric(userType: UserType, selectedServices: Seq[String])(implicit hc: HeaderCarrier): Future[TestUser] = { + println(s"ACHI: $selectedServices") + for { + services <- apiPlatformTestUserConnector.getServices() + testUser <- createUserWithServices(userType, services.filter(x => selectedServices.contains(x.key))) + } yield testUser + } private def createUserWithServices(userType: UserType, services: Seq[Service])(implicit hc: HeaderCarrier) = { diff --git a/app/uk/gov/hmrc/testuser/views/CreateTestUserViewGeneric.scala.html b/app/uk/gov/hmrc/testuser/views/CreateTestUserViewGeneric.scala.html new file mode 100644 index 0000000..80a4f95 --- /dev/null +++ b/app/uk/gov/hmrc/testuser/views/CreateTestUserViewGeneric.scala.html @@ -0,0 +1,137 @@ +@* + * 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 uk.gov.hmrc.testuser.models.NavLink +@import uk.gov.hmrc.testuser.controllers.CreateUserForm +@import uk.gov.hmrc.testuser.views.html.includes._ +@import uk.gov.hmrc.testuser.models.FieldDefinitions +@import uk.gov.hmrc.testuser.models.UserTypes.{INDIVIDUAL, ORGANISATION} +@import uk.gov.hmrc.testuser.views.html.govuk_wrapper +@import uk.gov.hmrc.testuser.models.views.FeedbackBanner +@import uk.gov.hmrc.testuser.models.views.GenericFeedbackBanner +@import uk.gov.hmrc.testuser.config.ApplicationConfig +@import uk.gov.hmrc.testuser.models.Service + + +@this(govUkWrapper: govuk_wrapper, feedbackBannerView: FeedbackBannerView) + +@(services: Seq[Service], navLinks: Seq[NavLink], form: Form[CreateUserForm], feedbackBanner: Option[FeedbackBanner] = Some(GenericFeedbackBanner))(implicit request: Request[_], messages: Messages, config: ApplicationConfig) + +@govUkWrapper(pageTitle = Some("Create test user - HMRC Developer Hub - GOV.UK"), navLinks = navLinks, feedbackBanner = feedbackBanner) { +
+ A test user is a dummy Government Gateway user ID used for testing a given service in the sandbox with the required enrolment. +
++ A test user ID has: +
++ Test users and other test data are no longer cleared down every two weeks. +
+ + + @helper.form(action = uk.gov.hmrc.testuser.controllers.routes.TestUserController.createUserGeneric()) { + @helper.CSRF.formField + ++ Login to { url.split(",")(0).replace("-", " ") } +
+ } + )) +} diff --git a/build.sbt b/build.sbt index 79fcabd..9f51780 100644 --- a/build.sbt +++ b/build.sbt @@ -1,16 +1,13 @@ -import play.core.PlayVersion -import play.sbt.PlayImport._ +import bloop.integrations.sbt.BloopDefaults import sbt.Tests.{Group, SubProcess} import uk.gov.hmrc.DefaultBuildSettings import uk.gov.hmrc.DefaultBuildSettings._ import uk.gov.hmrc.SbtAutoBuildPlugin import uk.gov.hmrc.sbtdistributables.SbtDistributablesPlugin import uk.gov.hmrc.sbtdistributables.SbtDistributablesPlugin._ -import uk.gov.hmrc.versioning.SbtGitVersioning import uk.gov.hmrc.versioning.SbtGitVersioning.autoImport.majorVersion import scala.util.Properties -import bloop.integrations.sbt.BloopDefaults lazy val playSettings: Seq[Setting[_]] = Seq.empty lazy val appName = "api-platform-test-user-frontend" diff --git a/conf/app.routes b/conf/app.routes index d00883c..4d95a1c 100644 --- a/conf/app.routes +++ b/conf/app.routes @@ -3,8 +3,10 @@ -> /hmrc-frontend hmrcfrontend.Routes GET / uk.gov.hmrc.testuser.controllers.TestUserController.showCreateUserPage() +GET /create uk.gov.hmrc.testuser.controllers.TestUserController.showCreateUserPageGeneric() POST /user uk.gov.hmrc.testuser.controllers.TestUserController.createUser() +POST /user/create uk.gov.hmrc.testuser.controllers.TestUserController.createUserGeneric() # Map static resources from the /public folder to the /assets URL path GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) diff --git a/conf/application.conf b/conf/application.conf index 80b3106..b3781ec 100644 --- a/conf/application.conf +++ b/conf/application.conf @@ -39,6 +39,14 @@ play.http.router=prod.Routes play.filters.enabled += play.filters.csp.CSPFilter play.filters.csp.directives.script-src = ${play.filters.csp.nonce.pattern} "'strict-dynamic' 'unsafe-inline' https: http:" +routing-login-urls = [ + "common-transit-convention-traders, http://localhost:9619/api-test-login/sign-in?continue=http://localhost:9485/manage-transit-movements" +] + +services = [ + "common-transit-convention-traders" +] + play.i18n.langs = [ "en" ] tracking-consent-frontend { diff --git a/conf/messages b/conf/messages index 3d58ae8..1c1736f 100644 --- a/conf/messages +++ b/conf/messages @@ -1,4 +1,5 @@ create.user.type.no.choice.field = Choose a test user type +create.user.services.no.choice.field = Choose the services you need footer.accessibility = Accessibility statement footer.cookies = Cookies diff --git a/project/plugins.sbt b/project/plugins.sbt index 6171cf2..c97b089 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,7 +4,7 @@ resolvers += Resolver.url("HMRC-open-artefacts-ivy", url("https://open.artefacts addSbtPlugin("uk.gov.hmrc" % "sbt-auto-build" % "3.9.0") addSbtPlugin("uk.gov.hmrc" % "sbt-distributables" % "2.2.0") addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.19") -addSbtPlugin("org.irundaia.sbt" % "sbt-sassify" % "1.5.1") +addSbtPlugin("org.irundaia.sbt" % "sbt-sassify" % "1.4.11") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.9.3") addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") diff --git a/test/uk/gov/hmrc/testuser/controllers/TestUserControllerSpec.scala b/test/uk/gov/hmrc/testuser/controllers/TestUserControllerSpec.scala index ad76ffd..d182a21 100644 --- a/test/uk/gov/hmrc/testuser/controllers/TestUserControllerSpec.scala +++ b/test/uk/gov/hmrc/testuser/controllers/TestUserControllerSpec.scala @@ -16,22 +16,16 @@ package uk.gov.hmrc.testuser.controllers -import scala.jdk.CollectionConverters._ -import scala.concurrent.ExecutionContext.Implicits.global -import scala.concurrent.Future.{failed, successful} - import akka.stream.Materializer import org.jsoup.Jsoup import org.jsoup.nodes.Document import org.scalatestplus.play.guice.GuiceOneAppPerSuite - import play.api.i18n.{Lang, MessagesApi} import play.api.mvc.{Action, AnyContent, AnyContentAsFormUrlEncoded, MessagesControllerComponents} import play.api.test.FakeRequest import play.api.test.Helpers._ import uk.gov.hmrc.http.UpstreamErrorResponse import uk.gov.hmrc.test.utils.AsyncHmrcSpec - import uk.gov.hmrc.testuser.ApplicationLogger import uk.gov.hmrc.testuser.common.LogSuppressing import uk.gov.hmrc.testuser.config.ApplicationConfig @@ -39,7 +33,11 @@ import uk.gov.hmrc.testuser.connectors.ApiPlatformTestUserConnector import uk.gov.hmrc.testuser.models.UserTypes.{INDIVIDUAL, ORGANISATION} import uk.gov.hmrc.testuser.models._ import uk.gov.hmrc.testuser.services.{NavigationService, TestUserService} -import uk.gov.hmrc.testuser.views.html.{CreateTestUserView, TestUserView} +import uk.gov.hmrc.testuser.views.html.{CreateTestUserView, CreateTestUserViewGeneric, TestUserView, TestUserViewGeneric} + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.Future.{failed, successful} +import scala.jdk.CollectionConverters._ class TestUserControllerSpec extends AsyncHmrcSpec with GuiceOneAppPerSuite with LogSuppressing with ApplicationLogger { @@ -66,7 +64,10 @@ class TestUserControllerSpec extends AsyncHmrcSpec with GuiceOneAppPerSuite with val mcc = app.injector.instanceOf[MessagesControllerComponents] val createTestUserView = app.injector.instanceOf[CreateTestUserView] + val createTestUserViewGeneric = app.injector.instanceOf[CreateTestUserViewGeneric] + val testUserView = app.injector.instanceOf[TestUserView] + val testUserViewGeneric = app.injector.instanceOf[TestUserViewGeneric] val mockTestUserService = mock[TestUserService] val mockNavigationService = mock[NavigationService] @@ -81,7 +82,9 @@ class TestUserControllerSpec extends AsyncHmrcSpec with GuiceOneAppPerSuite with mockApiPlatformTestUserConnector, mcc, createTestUserView, - testUserView + createTestUserViewGeneric, + testUserView, + testUserViewGeneric ) when(mockTestUserService.createUser(eqTo(INDIVIDUAL))(*)).thenReturn(successful(individual))