From 0d8faf7c830975145a21bdf2591bcec8bacd07e5 Mon Sep 17 00:00:00 2001 From: PaulCDurham <23658502+PaulCDurham@users.noreply.github.com> Date: Tue, 8 Oct 2024 15:15:38 +0100 Subject: [PATCH 1/4] Modify environment names --- .../application/AddCredentialController.scala | 6 +- .../EnvironmentAndCredentialsController.scala | 6 +- .../helpers/ApplicationApiBuilder.scala | 4 +- .../application/ApplicationLenses.scala | 5 +- app/models/application/EnvironmentName.scala | 8 +- .../application/ApplicationApi.scala | 7 +- .../EnvironmentAndCredentialsView.scala.html | 6 +- environment-parity.md | 160 ++++++++++++++++++ .../ApplicationsConnectorSpec.scala | 16 +- .../AddCredentialControllerSpec.scala | 6 +- ...ironmentAndCredentialsControllerSpec.scala | 10 +- ...equestProductionAccessControllerSpec.scala | 2 +- test/services/ApiHubServiceSpec.scala | 8 +- .../application/ApplicationApiSpec.scala | 14 +- 14 files changed, 211 insertions(+), 47 deletions(-) create mode 100644 environment-parity.md diff --git a/app/controllers/application/AddCredentialController.scala b/app/controllers/application/AddCredentialController.scala index c9102940..3b2bce7d 100644 --- a/app/controllers/application/AddCredentialController.scala +++ b/app/controllers/application/AddCredentialController.scala @@ -19,7 +19,7 @@ package controllers.application import controllers.actions._ import controllers.helpers.ErrorResultBuilder import forms.AddCredentialChecklistFormProvider -import models.application.{Application, Credential, Primary, Secondary} +import models.application.{Application, Credential, Production, Test} import models.exception.ApplicationCredentialLimitException import models.user.UserModel import play.api.i18n.{I18nSupport, Messages, MessagesApi} @@ -59,7 +59,7 @@ class AddCredentialController @Inject()( formWithErrors => Future.successful(BadRequest(view(formWithErrors, applicationId))), _ => - apiHubService.addCredential(request.application.id, Primary) flatMap { + apiHubService.addCredential(request.application.id, Production) flatMap { case Right(Some(credential)) => fetchApiNames(request.application).map( apiNames => @@ -74,7 +74,7 @@ class AddCredentialController @Inject()( def addDevelopmentCredential(applicationId: String): Action[AnyContent] = (identify andThen applicationAuth(applicationId)).async { implicit request => - apiHubService.addCredential(request.application.id, Secondary) flatMap { + apiHubService.addCredential(request.application.id, Test) flatMap { case Right(Some(_)) => Future.successful(SeeOther(controllers.application.routes.EnvironmentAndCredentialsController.onPageLoad(request.application.id).url)) case Right(None) => applicationNotFound(request.application) diff --git a/app/controllers/application/EnvironmentAndCredentialsController.scala b/app/controllers/application/EnvironmentAndCredentialsController.scala index 1ef37f66..be3c347a 100644 --- a/app/controllers/application/EnvironmentAndCredentialsController.scala +++ b/app/controllers/application/EnvironmentAndCredentialsController.scala @@ -20,7 +20,7 @@ import com.google.inject.Inject import config.FrontendAppConfig import controllers.actions.{ApplicationAuthActionProvider, IdentifierAction} import controllers.helpers.ErrorResultBuilder -import models.application.{EnvironmentName, Primary, Secondary} +import models.application.{EnvironmentName, Production, Test} import models.exception.ApplicationCredentialLimitException import models.user.Permissions import play.api.i18n.{I18nSupport, Messages} @@ -51,7 +51,7 @@ class EnvironmentAndCredentialsController @Inject()( request.identifierRequest.user.permissions match { case Permissions(_, true, _) | Permissions(_, _, true) => val url = s"${controllers.application.routes.EnvironmentAndCredentialsController.onPageLoad(id).url}#hip-production" - deleteCredential(id, clientId, Primary, url) + deleteCredential(id, clientId, Production, url) case _ => Future.successful(Redirect(controllers.routes.UnauthorisedController.onPageLoad)) } @@ -60,7 +60,7 @@ class EnvironmentAndCredentialsController @Inject()( def deleteSecondaryCredential(id: String, clientId: String): Action[AnyContent] = (identify andThen applicationAuth(id, enrich = true)).async { implicit request => val url = s"${controllers.application.routes.EnvironmentAndCredentialsController.onPageLoad(id).url}#hip-development" - deleteCredential(id, clientId, Secondary, url) + deleteCredential(id, clientId, Test, url) } private def deleteCredential(id: String, clientId: String, environmentName: EnvironmentName, url: String)(implicit request: Request[?]) = { diff --git a/app/controllers/helpers/ApplicationApiBuilder.scala b/app/controllers/helpers/ApplicationApiBuilder.scala index 36098ad2..c4f66ac9 100644 --- a/app/controllers/helpers/ApplicationApiBuilder.scala +++ b/app/controllers/helpers/ApplicationApiBuilder.scala @@ -54,8 +54,8 @@ class ApplicationApiBuilder @Inject()( endpointMethod.summary, endpointMethod.description, endpointMethod.scopes, - ApplicationEndpointAccess(application, hasPendingAccessRequest(apiDetail.id, pendingAccessRequests), endpointMethod, Primary), - ApplicationEndpointAccess(application, hasPendingAccessRequest(apiDetail.id, pendingAccessRequests), endpointMethod, Secondary) + ApplicationEndpointAccess(application, hasPendingAccessRequest(apiDetail.id, pendingAccessRequests), endpointMethod, Production), + ApplicationEndpointAccess(application, hasPendingAccessRequest(apiDetail.id, pendingAccessRequests), endpointMethod, Test) ) ) } diff --git a/app/models/application/ApplicationLenses.scala b/app/models/application/ApplicationLenses.scala index bf7a6f76..746d2875 100644 --- a/app/models/application/ApplicationLenses.scala +++ b/app/models/application/ApplicationLenses.scala @@ -149,8 +149,9 @@ object ApplicationLenses { def getCredentialsFor(environmentName: EnvironmentName): Seq[Credential] = { environmentName match { - case Primary => application.getPrimaryCredentials - case Secondary => application.getSecondaryCredentials + case Production => application.getPrimaryCredentials + case Test => application.getSecondaryCredentials + case _ => throw new IllegalArgumentException(s"Unsupported environment: $environmentName") // TODO } } diff --git a/app/models/application/EnvironmentName.scala b/app/models/application/EnvironmentName.scala index f33ee726..1bfe5a91 100644 --- a/app/models/application/EnvironmentName.scala +++ b/app/models/application/EnvironmentName.scala @@ -20,12 +20,14 @@ import models.{Enumerable, WithName} sealed trait EnvironmentName -case object Primary extends WithName("primary") with EnvironmentName -case object Secondary extends WithName("secondary") with EnvironmentName +case object Production extends WithName("primary") with EnvironmentName +case object PreProduction extends WithName("pre-production") with EnvironmentName +case object Test extends WithName("secondary") with EnvironmentName +case object Development extends WithName("development") with EnvironmentName object EnvironmentName extends Enumerable.Implicits { - val values: Seq[EnvironmentName] = Seq(Primary, Secondary) + val values: Seq[EnvironmentName] = Seq(Production, PreProduction, Test, Development) implicit val enumerable: Enumerable[EnvironmentName] = Enumerable(values.map(value => value.toString -> value)*) diff --git a/app/viewmodels/application/ApplicationApi.scala b/app/viewmodels/application/ApplicationApi.scala index 2f396622..b7761196 100644 --- a/app/viewmodels/application/ApplicationApi.scala +++ b/app/viewmodels/application/ApplicationApi.scala @@ -18,7 +18,7 @@ package viewmodels.application import models.{Enumerable, WithName} import models.api.{ApiDetail, EndpointMethod} -import models.application.{Api, Application, EnvironmentName, Primary, Secondary, SelectedEndpoint} +import models.application.{Api, Application, EnvironmentName, Production, Test, SelectedEndpoint} import models.application.ApplicationLenses.ApplicationLensOps import play.api.libs.json.{Format, Json, Writes} @@ -52,8 +52,9 @@ object ApplicationEndpointAccess extends Enumerable.Implicits{ ): ApplicationEndpointAccess = { val scopes = environmentName match { - case Primary => application.getPrimaryScopes - case Secondary => application.getSecondaryScopes + case Production => application.getPrimaryScopes + case Test => application.getSecondaryScopes + case _ => throw new IllegalArgumentException(s"Unsupported environment: $environmentName") // TODO } if (endpointMethod.scopes.toSet.subsetOf(scopes.map(_.name).toSet)) { diff --git a/app/views/application/EnvironmentAndCredentialsView.scala.html b/app/views/application/EnvironmentAndCredentialsView.scala.html index 8f3cc40f..15952d68 100644 --- a/app/views/application/EnvironmentAndCredentialsView.scala.html +++ b/app/views/application/EnvironmentAndCredentialsView.scala.html @@ -38,7 +38,7 @@ @canDeleteCredentials(environmentName: EnvironmentName) = @{ application.getCredentialsFor(environmentName).size > 1 && (user.permissions.canSupport || - (application.hasTeamMember(user) && (environmentName == Secondary || user.permissions.isPrivileged))) + (application.hasTeamMember(user) && (environmentName == Test || user.permissions.isPrivileged))) } @rolesGuidanceLink() = { @@ -90,7 +90,7 @@
@messages("environmentAndCredentials.clientId"): @@ -108,7 +108,7 @@
@messages("environmentAndCredentials.noCredentials")
} else { - @for(credential <- application.getPrimaryCredentials) { + @for(credential <- application.getProductionCredentials) {@messages("environmentAndCredentials.clientId"): diff --git a/test/controllers/AddAnApiSelectApplicationControllerSpec.scala b/test/controllers/AddAnApiSelectApplicationControllerSpec.scala index de203494..1ab688ed 100644 --- a/test/controllers/AddAnApiSelectApplicationControllerSpec.scala +++ b/test/controllers/AddAnApiSelectApplicationControllerSpec.scala @@ -360,14 +360,14 @@ class AddAnApiSelectApplicationControllerSpec extends SpecBase with MockitoSugar private def buildApplicationWithoutAccess(): Application = { FakeApplication .copy(id = "test-application-id-2", name = "test-application-name-2") - .setSecondaryScopes(Seq.empty) + .setTestScopes(Seq.empty) } private def buildApplicationsWithoutAccess(count: Int): Seq[Application] = { Seq.tabulate(count) { i => FakeApplication .copy(id = s"test-application-id-$i", name = s"test-application-name-$i") - .setSecondaryScopes(Seq.empty) + .setTestScopes(Seq.empty) } } diff --git a/test/controllers/application/ApplicationApisControllerSpec.scala b/test/controllers/application/ApplicationApisControllerSpec.scala index a5415861..73c6cd40 100644 --- a/test/controllers/application/ApplicationApisControllerSpec.scala +++ b/test/controllers/application/ApplicationApisControllerSpec.scala @@ -86,7 +86,7 @@ class ApplicationApisControllerSpec extends SpecBase with MockitoSugar with Test val application = FakeApplication .addApi(Api(apiDetail.id, apiDetail.title, Seq(SelectedEndpoint("GET", "/test")))) - .setSecondaryScopes(Seq(Scope("test-scope"))) + .setTestScopes(Seq(Scope("test-scope"))) val applicationApis = Seq( ApplicationApi(apiDetail, Seq(ApplicationEndpoint("GET", "/test", None, None, Seq("test-scope"), Inaccessible, Accessible)), false) diff --git a/test/controllers/application/ApplicationDetailsControllerSpec.scala b/test/controllers/application/ApplicationDetailsControllerSpec.scala index 5235a8a4..ef532fdf 100644 --- a/test/controllers/application/ApplicationDetailsControllerSpec.scala +++ b/test/controllers/application/ApplicationDetailsControllerSpec.scala @@ -154,7 +154,7 @@ class ApplicationDetailsControllerSpec extends SpecBase with MockitoSugar with T val application = FakeApplication .addApi(Api(apiDetail.id, apiDetail.title, Seq(SelectedEndpoint("GET", "/test")))) - .setSecondaryScopes(Seq(Scope("test-scope"))) + .setTestScopes(Seq(Scope("test-scope"))) val applicationApis = Seq( ApplicationApi(apiDetail, Seq(ApplicationEndpoint("GET", "/test", None, None, Seq("test-scope"), Inaccessible, Accessible)), false) @@ -189,7 +189,7 @@ class ApplicationDetailsControllerSpec extends SpecBase with MockitoSugar with T val application = FakeApplication .addApi(api) - .setSecondaryScopes(Seq(Scope("test-scope"))) + .setTestScopes(Seq(Scope("test-scope"))) val applicationApis = Seq( ApplicationApi(api, false) diff --git a/test/controllers/application/accessrequest/ProvideSupportingInformationControllerSpec.scala b/test/controllers/application/accessrequest/ProvideSupportingInformationControllerSpec.scala index 9d265404..1c52ec57 100644 --- a/test/controllers/application/accessrequest/ProvideSupportingInformationControllerSpec.scala +++ b/test/controllers/application/accessrequest/ProvideSupportingInformationControllerSpec.scala @@ -150,7 +150,7 @@ class ProvideSupportingInformationControllerSpec extends SpecBase with MockitoSu val application = FakeApplication .addApi(Api(apiDetail.id, apiDetail.title, Seq(SelectedEndpoint("GET", "/test")))) - .setSecondaryScopes(Seq(Scope("test-scope"))) + .setTestScopes(Seq(Scope("test-scope"))) application } diff --git a/test/controllers/application/accessrequest/RequestProductionAccessControllerSpec.scala b/test/controllers/application/accessrequest/RequestProductionAccessControllerSpec.scala index 5dfa9719..fe265e04 100644 --- a/test/controllers/application/accessrequest/RequestProductionAccessControllerSpec.scala +++ b/test/controllers/application/accessrequest/RequestProductionAccessControllerSpec.scala @@ -137,7 +137,7 @@ class RequestProductionAccessControllerSpec extends SpecBase with MockitoSugar w val application = FakeApplication .addApi(Api(apiDetail.id, apiDetail.title, Seq(SelectedEndpoint("GET", "/test")))) - .setSecondaryScopes(Seq(Scope("test-scope"))) + .setTestScopes(Seq(Scope("test-scope"))) application } diff --git a/test/controllers/application/accessrequest/RequestProductionAccessEndJourneyControllerSpec.scala b/test/controllers/application/accessrequest/RequestProductionAccessEndJourneyControllerSpec.scala index dd51db1c..dc0669b3 100644 --- a/test/controllers/application/accessrequest/RequestProductionAccessEndJourneyControllerSpec.scala +++ b/test/controllers/application/accessrequest/RequestProductionAccessEndJourneyControllerSpec.scala @@ -258,7 +258,7 @@ object RequestProductionAccessEndJourneyControllerSpec extends OptionValues{ private val anApplication = FakeApplication .addApi(Api(applicationApi.apiId, applicationApi.apiTitle, Seq(SelectedEndpoint("GET", "/test"), SelectedEndpoint("POST", "/anothertest")))) - .setSecondaryScopes(Seq(Scope("test-scope"))) + .setTestScopes(Seq(Scope("test-scope"))) private def buildApplicationApi(apiId: Int, endpointAccesses: Seq[ApplicationEndpointAccess]): ApplicationApi = { ApplicationApi( diff --git a/test/controllers/application/accessrequest/RequestProductionAccessStartControllerSpec.scala b/test/controllers/application/accessrequest/RequestProductionAccessStartControllerSpec.scala index ec09a55e..32e89acc 100644 --- a/test/controllers/application/accessrequest/RequestProductionAccessStartControllerSpec.scala +++ b/test/controllers/application/accessrequest/RequestProductionAccessStartControllerSpec.scala @@ -161,7 +161,7 @@ object RequestProductionAccessStartControllerSpec { private val application = FakeApplication .addApi(Api(apiDetail.id, apiDetail.title, Seq(SelectedEndpoint("GET", "/test")))) - .setSecondaryScopes(Seq(Scope("test-scope"))) + .setTestScopes(Seq(Scope("test-scope"))) private val applicationApi = ApplicationApi( apiDetail = apiDetail, diff --git a/test/controllers/helpers/ApplicationApiBuilderSpec.scala b/test/controllers/helpers/ApplicationApiBuilderSpec.scala index 68452e41..4df0c70b 100644 --- a/test/controllers/helpers/ApplicationApiBuilderSpec.scala +++ b/test/controllers/helpers/ApplicationApiBuilderSpec.scala @@ -47,8 +47,8 @@ class ApplicationApiBuilderSpec extends SpecBase with MockitoSugar { .addApi(Api(apiId1, apiTitle1, Seq(SelectedEndpoint("GET", "/test1/1"), SelectedEndpoint("POST", "/test1/1"), SelectedEndpoint("GET", "/test1/2")))) .addApi(Api(apiId2, apiTitle2, Seq(SelectedEndpoint("GET", "/test2/1")))) .addApi(Api(apiId3, apiTitle3, Seq(SelectedEndpoint("GET", "/test3/1")))) - .setPrimaryScopes(scopes("all:test-scope-1", "get:test-scope-1-1", "get:test-scope-1-2")) - .setSecondaryScopes(scopes("all:test-scope-1", "get:test-scope-1-1", "post:test-scope-1-1", "get:test-scope-1-2", "get:test-scope-3-1")) + .setProductionScopes(scopes("all:test-scope-1", "get:test-scope-1-1", "get:test-scope-1-2")) + .setTestScopes(scopes("all:test-scope-1", "get:test-scope-1-1", "post:test-scope-1-1", "get:test-scope-1-2", "get:test-scope-3-1")) when(fixture.apiHubService.getApiDetail(eqTo(apiId1))(any())) .thenReturn(Future.successful(Some(apiDetail1))) diff --git a/test/models/application/ApplicationLensesSpec.scala b/test/models/application/ApplicationLensesSpec.scala index f15fa088..381b7d55 100644 --- a/test/models/application/ApplicationLensesSpec.scala +++ b/test/models/application/ApplicationLensesSpec.scala @@ -27,22 +27,22 @@ import scala.util.Random class ApplicationLensesSpec extends LensBehaviours { - "applicationEnvironments" - { - "must get the correct Environments" in { - val expected = randomEnvironments() - val application = testApplication.copy(environments = expected) - - val actual = applicationEnvironments.get(application) - actual mustBe expected - } - - "must set the Environments correctly" in { - val expected = randomEnvironments() - val application = applicationEnvironments.set(testApplication, expected) - - application.environments mustBe expected - } - } +// "applicationEnvironments" - { +// "must get the correct Environments" in { +// val expected = randomEnvironments() +// val application = testApplication.copy(environments = expected) +// +// val actual = applicationEnvironments.get(application) +// actual mustBe expected +// } +// +// "must set the Environments correctly" in { +// val expected = randomEnvironments() +// val application = applicationEnvironments.set(testApplication, expected) +// +// application.environments mustBe expected +// } +// } "environmentScopes" - { "must get the correct Scopes" in { @@ -80,19 +80,19 @@ class ApplicationLensesSpec extends LensBehaviours { } } - "environmentPrimary" - { - "must" - { - behave like environmentsToEnvironmentLens( - environmentPrimary, - _.primary - ) - } - } +// "environmentPrimary" - { +// "must" - { +// behave like environmentsToEnvironmentLens( +// environmentProduction, +// _.primary +// ) +// } +// } "applicationPrimary" - { "must" - { behave like applicationToEnvironmentLens( - applicationPrimary, + applicationProduction, _.primary ) } @@ -101,7 +101,7 @@ class ApplicationLensesSpec extends LensBehaviours { "applicationPrimaryScopes" - { "must" - { behave like applicationToScopesLens( - applicationPrimaryScopes, + applicationProductionScopes, _.primary ) } @@ -110,25 +110,25 @@ class ApplicationLensesSpec extends LensBehaviours { "applicationPrimaryCredentials" - { "must" - { behave like applicationToCredentialsLens( - applicationPrimaryCredentials, + applicationProductionCredentials, _.primary ) } } - "environmentSecondary" - { - "must" - { - behave like environmentsToEnvironmentLens( - environmentSecondary, - _.secondary - ) - } - } +// "environmentSecondary" - { +// "must" - { +// behave like environmentsToEnvironmentLens( +// environmentTest, +// _.secondary +// ) +// } +// } "applicationSecondary" - { "must" - { behave like applicationToEnvironmentLens( - applicationSecondary, + applicationTest, _.secondary ) } @@ -137,7 +137,7 @@ class ApplicationLensesSpec extends LensBehaviours { "applicationSecondaryScopes" - { "must" - { behave like applicationToScopesLens( - applicationSecondaryScopes, + applicationTestScopes, _.secondary ) } @@ -146,7 +146,7 @@ class ApplicationLensesSpec extends LensBehaviours { "applicationSecondaryCredentials" - { "must" - { behave like applicationToCredentialsLens( - applicationSecondaryCredentials, + applicationTestCredentials, _.secondary ) } @@ -186,8 +186,8 @@ class ApplicationLensesSpec extends LensBehaviours { "getPrimaryScopes" - { "must" - { behave like applicationScopesGetterFunction( - applicationPrimaryScopes, - application => ApplicationLensOps(application).getPrimaryScopes + applicationProductionScopes, + application => ApplicationLensOps(application).getProductionScopes ) } } @@ -195,8 +195,8 @@ class ApplicationLensesSpec extends LensBehaviours { "setPrimaryScopes" - { "must" - { behave like applicationScopesSetterFunction( - applicationPrimaryScopes, - (application, scopes) => ApplicationLensOps(application).setPrimaryScopes(scopes) + applicationProductionScopes, + (application, scopes) => ApplicationLensOps(application).setProductionScopes(scopes) ) } } @@ -204,8 +204,8 @@ class ApplicationLensesSpec extends LensBehaviours { "addPrimaryScope" - { "must" - { behave like applicationAddScopeFunction( - applicationPrimaryScopes, - (application, scope) => ApplicationLensOps(application).addPrimaryScope(scope) + applicationProductionScopes, + (application, scope) => ApplicationLensOps(application).addProductionScope(scope) ) } } @@ -217,17 +217,17 @@ class ApplicationLensesSpec extends LensBehaviours { val credential2 = randomCredential().copy(created = LocalDateTime.now().minusDays(2)) val application = testApplication - .setPrimaryCredentials(Seq(credential1, master, credential2)) + .setProductionCredentials(Seq(credential1, master, credential2)) - application.getPrimaryMasterCredential mustBe Some(master) + application.getProductionMasterCredential mustBe Some(master) } } "getPrimaryCredentials" - { "must" - { behave like applicationCredentialsGetterFunction( - applicationPrimaryCredentials, - application => ApplicationLensOps(application).getPrimaryCredentials + applicationProductionCredentials, + application => ApplicationLensOps(application).getProductionCredentials ) } } @@ -235,8 +235,8 @@ class ApplicationLensesSpec extends LensBehaviours { "setPrimaryCredentials" - { "must" - { behave like applicationCredentialsSetterFunction( - applicationPrimaryCredentials, - (application, credentials) => ApplicationLensOps(application).setPrimaryCredentials(credentials) + applicationProductionCredentials, + (application, credentials) => ApplicationLensOps(application).setProductionCredentials(credentials) ) } } @@ -244,8 +244,8 @@ class ApplicationLensesSpec extends LensBehaviours { "addPrimaryCredential" - { "must" - { behave like applicationAddCredentialFunction( - applicationPrimaryCredentials, - (application, credential) => ApplicationLensOps(application).addPrimaryCredential(credential) + applicationProductionCredentials, + (application, credential) => ApplicationLensOps(application).addProductionCredential(credential) ) } } @@ -253,8 +253,8 @@ class ApplicationLensesSpec extends LensBehaviours { "getSecondaryScopes" - { "must" - { behave like applicationScopesGetterFunction( - applicationSecondaryScopes, - application => ApplicationLensOps(application).getSecondaryScopes + applicationTestScopes, + application => ApplicationLensOps(application).getTestScopes ) } } @@ -262,8 +262,8 @@ class ApplicationLensesSpec extends LensBehaviours { "setSecondaryScopes" - { "must" - { behave like applicationScopesSetterFunction( - applicationSecondaryScopes, - (application, scopes) => ApplicationLensOps(application).setSecondaryScopes(scopes) + applicationTestScopes, + (application, scopes) => ApplicationLensOps(application).setTestScopes(scopes) ) } } @@ -271,8 +271,8 @@ class ApplicationLensesSpec extends LensBehaviours { "addSecondaryScope" - { "must" - { behave like applicationAddScopeFunction( - applicationSecondaryScopes, - (application, scope) => ApplicationLensOps(application).addSecondaryScope(scope) + applicationTestScopes, + (application, scope) => ApplicationLensOps(application).addTestScope(scope) ) } } @@ -284,17 +284,17 @@ class ApplicationLensesSpec extends LensBehaviours { val credential2 = randomCredential().copy(created = LocalDateTime.now().minusDays(2)) val application = testApplication - .setSecondaryCredentials(Seq(credential1, master, credential2)) + .setTestCredentials(Seq(credential1, master, credential2)) - application.getSecondaryMasterCredential mustBe Some(master) + application.getTestMasterCredential mustBe Some(master) } } "getSecondaryCredentials" - { "must" - { behave like applicationCredentialsGetterFunction( - applicationSecondaryCredentials, - application => ApplicationLensOps(application).getSecondaryCredentials + applicationTestCredentials, + application => ApplicationLensOps(application).getTestCredentials ) } } @@ -302,8 +302,8 @@ class ApplicationLensesSpec extends LensBehaviours { "setSecondaryCredentials" - { "must" - { behave like applicationCredentialsSetterFunction( - applicationSecondaryCredentials, - (application, credentials) => ApplicationLensOps(application).setSecondaryCredentials(credentials) + applicationTestCredentials, + (application, credentials) => ApplicationLensOps(application).setTestCredentials(credentials) ) } } @@ -311,8 +311,8 @@ class ApplicationLensesSpec extends LensBehaviours { "addSecondaryCredential" - { "must" - { behave like applicationAddCredentialFunction( - applicationSecondaryCredentials, - (application, credential) => ApplicationLensOps(application).addSecondaryCredential(credential) + applicationTestCredentials, + (application, credential) => ApplicationLensOps(application).addTestCredential(credential) ) } } @@ -364,14 +364,14 @@ class ApplicationLensesSpec extends LensBehaviours { Scope("test-scope-2") ) - val application = testApplication.setSecondaryScopes(scopes) + val application = testApplication.setTestScopes(scopes) val actual = application.getRequiredScopeNames actual must contain theSameElementsAs Set("test-scope-1", "test-scope-2") } "must return an empty set when there are no secondary scopes" in { - val application = testApplication.setSecondaryScopes(Seq.empty) + val application = testApplication.setTestScopes(Seq.empty) val actual = application.getRequiredScopeNames actual mustBe empty diff --git a/test/viewmodels/application/ApplicationApiSpec.scala b/test/viewmodels/application/ApplicationApiSpec.scala index 71244a91..54fd7e48 100644 --- a/test/viewmodels/application/ApplicationApiSpec.scala +++ b/test/viewmodels/application/ApplicationApiSpec.scala @@ -32,7 +32,7 @@ class ApplicationApiSpec extends AnyFreeSpec with Matchers with ScalaCheckProper "ApplicationEndpointAccess" - { "must return Accessible when an application has the scopes required by the endpoint" in { - val application = FakeApplication.setPrimaryScopes(scopes(testScope1, testScope2, testScope3)) + val application = FakeApplication.setProductionScopes(scopes(testScope1, testScope2, testScope3)) val endpointMethod = EndpointMethod("GET", None, None, Seq(testScope1, testScope3)) val actual = ApplicationEndpointAccess(application, false, endpointMethod, Production) @@ -40,7 +40,7 @@ class ApplicationApiSpec extends AnyFreeSpec with Matchers with ScalaCheckProper } "must return Inaccessible when an application does not have the scopes required by the endpoint" in { - val application = FakeApplication.setPrimaryScopes(scopes(testScope1)) + val application = FakeApplication.setProductionScopes(scopes(testScope1)) val endpointMethod = EndpointMethod("GET", None, None, Seq(testScope2, testScope3)) val actual = ApplicationEndpointAccess(application, false, endpointMethod, Production) @@ -48,7 +48,7 @@ class ApplicationApiSpec extends AnyFreeSpec with Matchers with ScalaCheckProper } "must return Inaccessible when an application only has a subset of the scopes required by the endpoint" in { - val application = FakeApplication.setPrimaryScopes(scopes(testScope1, testScope2)) + val application = FakeApplication.setProductionScopes(scopes(testScope1, testScope2)) val endpointMethod = EndpointMethod("GET", None, None, Seq(testScope2, testScope3)) val actual = ApplicationEndpointAccess(application, false, endpointMethod, Production) @@ -56,7 +56,7 @@ class ApplicationApiSpec extends AnyFreeSpec with Matchers with ScalaCheckProper } "must return Inaccessible when an application has the scopes required but in the wrong environment" in { - val application = FakeApplication.setPrimaryScopes(scopes("test-scope-1", "test-scope-2", "test-scope-3")) + val application = FakeApplication.setProductionScopes(scopes("test-scope-1", "test-scope-2", "test-scope-3")) val endpointMethod = EndpointMethod("GET", None, None, Seq("test-scope-1", "test-scope-3")) val actual = ApplicationEndpointAccess(application, false, endpointMethod, Test) @@ -64,7 +64,7 @@ class ApplicationApiSpec extends AnyFreeSpec with Matchers with ScalaCheckProper } "must return Requested for a primary endpoint without required scopes when there is a pending production access request" in { - val application = FakeApplication.setPrimaryScopes(scopes(testScope1)) + val application = FakeApplication.setProductionScopes(scopes(testScope1)) val endpointMethod = EndpointMethod("GET", None, None, Seq(testScope2, testScope3)) val actual = ApplicationEndpointAccess(application, true, endpointMethod, Production) @@ -72,7 +72,7 @@ class ApplicationApiSpec extends AnyFreeSpec with Matchers with ScalaCheckProper } "must return Accessible for a primary endpoint with required scopes when there is a pending production access request" in { - val application = FakeApplication.setPrimaryScopes(scopes(testScope1, testScope2, testScope3)) + val application = FakeApplication.setProductionScopes(scopes(testScope1, testScope2, testScope3)) val endpointMethod = EndpointMethod("GET", None, None, Seq(testScope1, testScope3)) val actual = ApplicationEndpointAccess(application, true, endpointMethod, Production) From e410bd164fd6071a94bdc25c8678766488702870 Mon Sep 17 00:00:00 2001 From: PaulCDurham <23658502+PaulCDurham@users.noreply.github.com> Date: Wed, 9 Oct 2024 17:01:57 +0100 Subject: [PATCH 3/4] Environment config --- app/config/Environments.scala | 65 +++++ app/config/Module.scala | 3 +- .../EnvironmentAndCredentialsController.scala | 9 +- .../EnvironmentAndCredentialsView.scala.html | 61 ++++- environment-parity.md | 222 +++++++++++++----- ...ironmentAndCredentialsControllerSpec.scala | 13 +- 6 files changed, 291 insertions(+), 82 deletions(-) create mode 100644 app/config/Environments.scala diff --git a/app/config/Environments.scala b/app/config/Environments.scala new file mode 100644 index 00000000..9af43dfb --- /dev/null +++ b/app/config/Environments.scala @@ -0,0 +1,65 @@ +/* + * Copyright 2024 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 config + +import com.google.inject.{Inject, Singleton} +import models.application.{Development, EnvironmentName, PreProduction, Production, Test} +import play.api.Logging +import play.api.libs.json.{Format, Json} + +case class EnvironmentConfig(environmentName: EnvironmentName, on: Boolean) + +object EnvironmentConfig { + + implicit val formatEnvironmentConfig: Format[EnvironmentConfig] = Json.format[EnvironmentConfig] + +} + +case class EnvironmentsConfig( + production: EnvironmentConfig, + preProduction: EnvironmentConfig, + test: EnvironmentConfig, + development: EnvironmentConfig +) + +object EnvironmentsConfig { + + implicit val formatEnvironmentsConfig: Format[EnvironmentsConfig] = Json.format[EnvironmentsConfig] + +} + +trait Environments { + + def config: EnvironmentsConfig + +} + +@Singleton +class EnvironmentsImpl @Inject() extends Environments with Logging { + + private val environmentsConfig = EnvironmentsConfig( + production = EnvironmentConfig(Production, on = true), + preProduction = EnvironmentConfig(PreProduction, on = true), + test = EnvironmentConfig(Test, on = true), + development = EnvironmentConfig(Development, on = true) + ) + + logger.info(s"Environment configuration${System.lineSeparator()}${Json.prettyPrint(Json.toJson(config))}") + + override def config: EnvironmentsConfig = environmentsConfig + +} diff --git a/app/config/Module.scala b/app/config/Module.scala index ce88c807..1c4458f0 100644 --- a/app/config/Module.scala +++ b/app/config/Module.scala @@ -47,7 +47,8 @@ class Module extends play.api.inject.Module { bindz[Domains].to(classOf[DomainsImpl]).eagerly(), bindz[Hods].to(classOf[HodsImpl]).eagerly(), bindz[Platforms].to(classOf[PlatformsImpl]).eagerly(), - bindz[EmailDomains].to(classOf[EmailDomainsImpl]).eagerly() + bindz[EmailDomains].to(classOf[EmailDomainsImpl]).eagerly(), + bindz[Environments].to(classOf[EnvironmentsImpl]).eagerly() ) val authTokenInitialiserBindings: Seq[Binding[?]] = if (configuration.get[Boolean]("create-internal-auth-token-on-start")) { diff --git a/app/controllers/application/EnvironmentAndCredentialsController.scala b/app/controllers/application/EnvironmentAndCredentialsController.scala index be3c347a..46442895 100644 --- a/app/controllers/application/EnvironmentAndCredentialsController.scala +++ b/app/controllers/application/EnvironmentAndCredentialsController.scala @@ -17,14 +17,14 @@ package controllers.application import com.google.inject.Inject -import config.FrontendAppConfig +import config.{Environments, FrontendAppConfig} import controllers.actions.{ApplicationAuthActionProvider, IdentifierAction} import controllers.helpers.ErrorResultBuilder import models.application.{EnvironmentName, Production, Test} import models.exception.ApplicationCredentialLimitException import models.user.Permissions import play.api.i18n.{I18nSupport, Messages} -import play.api.mvc._ +import play.api.mvc.* import services.ApiHubService import uk.gov.hmrc.play.bootstrap.frontend.controller.FrontendBaseController import views.html.application.EnvironmentAndCredentialsView @@ -38,12 +38,13 @@ class EnvironmentAndCredentialsController @Inject()( view: EnvironmentAndCredentialsView, apiHubService: ApiHubService, errorResultBuilder: ErrorResultBuilder, - config: FrontendAppConfig + config: FrontendAppConfig, + environments: Environments )(implicit ec: ExecutionContext) extends FrontendBaseController with I18nSupport { def onPageLoad(id: String): Action[AnyContent] = (identify andThen applicationAuth(id, enrich = true)) { implicit request => - Ok(view(request.application, request.identifierRequest.user, config.helpDocsPath)) + Ok(view(request.application, request.identifierRequest.user, config.helpDocsPath, environments)) } def deletePrimaryCredential(id: String, clientId: String): Action[AnyContent] = (identify andThen applicationAuth(id, enrich = true)).async { diff --git a/app/views/application/EnvironmentAndCredentialsView.scala.html b/app/views/application/EnvironmentAndCredentialsView.scala.html index 8f0a176b..f86d3524 100644 --- a/app/views/application/EnvironmentAndCredentialsView.scala.html +++ b/app/views/application/EnvironmentAndCredentialsView.scala.html @@ -14,6 +14,7 @@ * limitations under the License. *@ +@import config.Environments @import models.application._ @import models.application.ApplicationLenses._ @import models.user.UserModel @@ -29,7 +30,7 @@ iconsLink: IconsLink ) -@(application: Application, user: UserModel, apiHubGuideUrl: String)(implicit request: Request[?], messages: Messages) +@(application: Application, user: UserModel, apiHubGuideUrl: String, environments: Environments)(implicit request: Request[?], messages: Messages) @sortCredentials(credentials: Seq[Credential]) = @{ credentials.sortWith((a, b) => a.created.isBefore(b.created)) @@ -45,7 +46,7 @@ @messages("environmentAndCredentials.notPrivileged.additional3") } -@developmentTab() = { +@testTab() = {