From 65c07d7f3d16bb784b7b9f80b3fc4838e71f89ba Mon Sep 17 00:00:00 2001 From: Sam Sloman Date: Mon, 30 Sep 2024 17:58:08 +0100 Subject: [PATCH 1/5] BDOG-3206: adds route types for service info page --- .../CatalogueController.scala | 28 ++- .../connector/RouteRulesConnector.scala | 153 ++++++++-------- .../connector/SearchByUrlConnector.scala | 1 + .../service/RouteRulesService.scala | 83 ++++----- .../service/SearchByUrlService.scala | 10 +- .../shuttering/ShutterService.scala | 14 +- .../view/ServiceInfoPage.scala.html | 17 +- .../serviceRouteRuleViolations.scala.html | 8 +- .../partials/serviceUrlDetails.scala.html | 116 +++++++++--- .../whatsrunningwhere/ReleasesConnector.scala | 23 ++- .../cataloguefrontend/ServicePageSpec.scala | 3 +- .../connector/RouteRulesConnectorSpec.scala | 64 +++---- .../cataloguefrontend/jsondata/JsonData.scala | 68 +++---- .../service/RouteRulesServiceSpec.scala | 170 ++++++------------ .../shuttering/ShutterServiceSpec.scala | 29 ++- .../view/partials/html/DetailsSpec.scala | 8 +- .../html/ServiceRouteRuleViolationsSpec.scala | 84 ++++----- 17 files changed, 468 insertions(+), 411 deletions(-) diff --git a/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala b/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala index 2ba3efe40..437fbe5cf 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala @@ -27,9 +27,11 @@ import play.twirl.api.Html import uk.gov.hmrc.cataloguefrontend.auth.{AuthController, CatalogueAuthBuilders} import uk.gov.hmrc.cataloguefrontend.connector.BuildDeployApiConnector.PrototypeStatus import uk.gov.hmrc.cataloguefrontend.connector.* +import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} import uk.gov.hmrc.cataloguefrontend.connector.model.RepositoryModules import uk.gov.hmrc.cataloguefrontend.cost.{CostEstimateConfig, CostEstimationService, Zone} import uk.gov.hmrc.cataloguefrontend.leakdetection.LeakDetectionService +import uk.gov.hmrc.cataloguefrontend.model.Environment.Production import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName, SlugInfoFlag, TeamName, Version} import uk.gov.hmrc.cataloguefrontend.prcommenter.PrCommenterConnector import uk.gov.hmrc.cataloguefrontend.service.{DefaultBranchesService, RouteRulesService} @@ -37,8 +39,8 @@ import uk.gov.hmrc.cataloguefrontend.serviceconfigs.{ServiceConfigsConnector, Se import uk.gov.hmrc.cataloguefrontend.shuttering.{ShutterService, ShutterState, ShutterType} import uk.gov.hmrc.cataloguefrontend.util.TelemetryLinks import uk.gov.hmrc.cataloguefrontend.servicecommissioningstatus.{LifecycleStatus, ServiceCommissioningStatusConnector} -import uk.gov.hmrc.cataloguefrontend.vulnerabilities.{TotalVulnerabilityCount, VulnerabilitiesConnector, VulnerabilitySummary, CurationStatus} -import uk.gov.hmrc.cataloguefrontend.whatsrunningwhere.WhatsRunningWhereService +import uk.gov.hmrc.cataloguefrontend.vulnerabilities.{CurationStatus, TotalVulnerabilityCount, VulnerabilitiesConnector, VulnerabilitySummary} +import uk.gov.hmrc.cataloguefrontend.whatsrunningwhere.{ReleasesConnector, WhatsRunningWhereService} import uk.gov.hmrc.http.HeaderCarrier import uk.gov.hmrc.internalauth.client.{FrontendAuthComponents, IAAction, Predicate, Resource, Retrieval} import uk.gov.hmrc.internalauth.client.Predicate.Permission @@ -63,8 +65,8 @@ class CatalogueController @Inject() ( teamsAndRepositoriesConnector : TeamsAndRepositoriesConnector, serviceConfigsService : ServiceConfigsService, costEstimationService : CostEstimationService, - costEstimateConfig : CostEstimateConfig, routeRulesService : RouteRulesService, + costEstimateConfig : CostEstimateConfig, serviceDependenciesConnector : ServiceDependenciesConnector, serviceCommissioningStatusConnector: ServiceCommissioningStatusConnector, leakDetectionService : LeakDetectionService, @@ -86,6 +88,8 @@ class CatalogueController @Inject() ( defaultBranchListPage : DefaultBranchListPage, serviceMetricsConnector : ServiceMetricsConnector, serviceConfigsConnector : ServiceConfigsConnector, + releasesConnector : ReleasesConnector, + routesRulesConnector : RouteRulesConnector, override val auth : FrontendAuthComponents )(using override val ec: ExecutionContext @@ -195,7 +199,18 @@ class CatalogueController @Inject() ( .map(_.collect { case Some(v) => v }.toMap) latestRepoModules <- serviceDependenciesConnector.getRepositoryModulesLatestVersion(repositoryName) urlIfLeaksFound <- leakDetectionService.urlIfLeaksFound(repositoryName) - serviceRoutes <- routeRulesService.serviceRoutes(serviceName) + routes <- routesRulesConnector.routes(serviceName) + prodApiServices <- releasesConnector.apiServices(Environment.Production) + apiRoutes = prodApiServices.collect: + case api if api.serviceName == serviceName => + Route( + path = api.context, + ruleConfigurationUrl = None, + routeType = RouteType.ApiContext, + environment = api.environment + ) + allRoutes = (routes ++ apiRoutes).filter(_.environment == Environment.Production) + inconsistentRoutesCheck = routeRulesService.serviceRoutes(routes) optLatestServiceInfo <- serviceDependenciesConnector.getSlugInfo(serviceName) serviceCostEstimate <- costEstimationService.estimateServiceCost(serviceName) commenterReport <- prCommenterConnector.report(repositoryName) @@ -226,14 +241,15 @@ class CatalogueController @Inject() ( repositoryCreationDate = repositoryDetails.createdDate, envDatas = optLatestData.fold(envDatas)(envDatas + _), linkToLeakDetection = urlIfLeaksFound, - serviceRoutes = serviceRoutes, + allRoutes = allRoutes, + serviceRoutes = inconsistentRoutesCheck, hasBranchProtectionAuth = hasBranchProtectionAuth, commenterReport = commenterReport, serviceRelationships = serviceRelationships, canMarkForDecommissioning = canMarkForDecommissioning, lifecycle = lifecycle, testJobMap = testJobMap, - isGuest = isGuest + isGuest = isGuest, )) def library(name: String): Action[AnyContent] = diff --git a/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala b/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala index 83b1be6b4..71fa94efa 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala @@ -17,8 +17,8 @@ package uk.gov.hmrc.cataloguefrontend.connector import play.api.Logger -import play.api.libs.functional.syntax._ -import play.api.libs.json.{Reads, __} +import play.api.libs.functional.syntax.* +import play.api.libs.json.{JsResult, Reads, __} import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName} import uk.gov.hmrc.http.{HeaderCarrier, HttpReads, StringContextOps} import uk.gov.hmrc.http.client.HttpClientV2 @@ -40,92 +40,101 @@ class RouteRulesConnector @Inject() ( private val baseUrl: String = servicesConfig.baseUrl("service-configs") - def frontendServices()(using HeaderCarrier): Future[Seq[String]] = - val url = url"$baseUrl/service-configs/frontend-services" - httpClientV2.get(url) - .execute[Seq[String]] - .recover: - case NonFatal(ex) => - logger.error(s"An error occurred when connecting to $url: ${ex.getMessage}", ex) - Seq.empty - - def frontendRoutes(service: ServiceName)(using HeaderCarrier): Future[Seq[EnvironmentRoute]] = - val url = url"$baseUrl/service-configs/frontend-route/${service.asString}" - given Reads[EnvironmentRoute] = EnvironmentRoute.reads + def routes( + service : ServiceName + , routeType : Option[RouteType] = None + , environment: Option[Environment] = None + )(using + HeaderCarrier + ): Future[Seq[Route]] = + val url = url"$baseUrl/service-configs/routes/${service.asString}" + given Reads[Route] = Route.reads httpClientV2 .get(url) - .execute[Seq[EnvironmentRoute]] + .execute[Seq[Route]] .recover: case NonFatal(ex) => logger.error(s"An error occurred when connecting to $url: ${ex.getMessage}", ex) Seq.empty - def adminFrontendRoutes(service: ServiceName)(using HeaderCarrier): Future[Seq[EnvironmentRoute]] = - val url = url"$baseUrl/service-configs/admin-frontend-route/${service.asString}" - given Reads[AdminFrontendRoute] = AdminFrontendRoute.reads - httpClientV2 - .get(url) - .execute[Seq[AdminFrontendRoute]] - .map: - _ - .flatMap: raw => - raw.allow.keys.map: env => - EnvironmentRoute( - environment = env - , routes = Seq(Route( - frontendPath = raw.route - , ruleConfigurationUrl = raw.location - , isRegex = false - )) - ) - .groupBy(_.environment) - .toSeq - .map: (k, v) => - EnvironmentRoute(k, v.flatMap(_.routes.sortBy(_.ruleConfigurationUrl)), isAdmin = true) + def frontendServices()(using HeaderCarrier): Future[Seq[String]] = + val url = url"$baseUrl/service-configs/frontend-services" + httpClientV2.get(url) + .execute[Seq[String]] .recover: case NonFatal(ex) => logger.error(s"An error occurred when connecting to $url: ${ex.getMessage}", ex) Seq.empty -object RouteRulesConnector: - case class Route( - frontendPath : String - , ruleConfigurationUrl: String - , isRegex : Boolean = false - ) +// // Used by ShutterService, replace with query param for Frontend Routes only +// def frontendRoutes(service: ServiceName)(using HeaderCarrier): Future[Seq[EnvironmentRoute]] = +// val url = url"$baseUrl/service-configs/frontend-route/${service.asString}" +// given Reads[EnvironmentRoute] = EnvironmentRoute.reads +// httpClientV2 +// .get(url) +// .execute[Seq[EnvironmentRoute]] +// .recover: +// case NonFatal(ex) => +// logger.error(s"An error occurred when connecting to $url: ${ex.getMessage}", ex) +// Seq.empty + +// def adminFrontendRoutes(service: ServiceName)(using HeaderCarrier): Future[Seq[EnvironmentRoute]] = +// val url = url"$baseUrl/service-configs/admin-frontend-route/${service.asString}" +// given Reads[AdminFrontendRoute] = AdminFrontendRoute.reads +// httpClientV2 +// .get(url) +// .execute[Seq[AdminFrontendRoute]] +// .map: +// _ +// .flatMap: raw => +// raw.allow.keys.map: env => +// EnvironmentRoute( +// environment = env +// , routes = Seq(Route( +// frontendPath = raw.route +// , ruleConfigurationUrl = raw.location +// , isRegex = false +// )) +// ) +// .groupBy(_.environment) +// .toSeq +// .map: (k, v) => +// EnvironmentRoute(k, v.flatMap(_.routes.sortBy(_.ruleConfigurationUrl)), isAdmin = true) +// .recover: +// case NonFatal(ex) => +// logger.error(s"An error occurred when connecting to $url: ${ex.getMessage}", ex) +// Seq.empty - case class EnvironmentRoute( - environment: Environment - , routes : Seq[Route] - , isAdmin : Boolean = false - ) +object RouteRulesConnector: + import uk.gov.hmrc.cataloguefrontend.util.{FromString, FromStringEnum, Parser} + import FromStringEnum._ - object EnvironmentRoute: - val reads: Reads[EnvironmentRoute] = - given Reads[Route] = - ( (__ \"frontendPath" ).read[String] - ~ (__ \"ruleConfigurationUrl").read[String] - ~ (__ \"isRegex" ).read[Boolean] - )(Route.apply) + given Parser[RouteType] = Parser.parser(RouteType.values) - ( (__ \"environment").read[Environment] - ~ (__ \"routes" ).read[Seq[Route]] - ~ Reads.pure(false) - )(EnvironmentRoute.apply) + enum RouteType( + val asString : String, + val displayString: String + ) extends FromString + derives Ordering, Reads: + case Frontend extends RouteType(asString = "frontend" , displayString = "Frontend" ) + case AdminFrontend extends RouteType(asString = "adminfrontend", displayString = "Admin Frontend") + case Devhub extends RouteType(asString = "devhub" , displayString = "Devhub" ) + case ApiContext extends RouteType(asString = "apicontext" , displayString = "Api Context" ) - case class AdminFrontendRoute( - service : ServiceName - , route : String - , allow : Map[Environment, List[String]] - , location: String + case class Route( + path : String + , ruleConfigurationUrl: Option[String] + , isRegex : Boolean = false + , routeType : RouteType + , environment : Environment ) - object AdminFrontendRoute: - val reads: Reads[AdminFrontendRoute] = - ( (__ \"service" ).read[ServiceName] - ~ (__ \"route" ).read[String] - ~ (__ \"allow" ).read[Map[Environment, List[String]]] - ~ (__ \"location").read[String] - )(AdminFrontendRoute.apply) - + object Route: + val reads: Reads[Route] = + ( (__ \ "path" ).read[String] + ~ (__ \ "ruleConfigurationUrl").readNullable[String] + ~ (__ \ "isRegex" ).readWithDefault[Boolean](false) + ~ (__ \ "routeType" ).read[RouteType] + ~ (__ \ "environment" ).read[Environment] + )(Route.apply) end RouteRulesConnector diff --git a/app/uk/gov/hmrc/cataloguefrontend/connector/SearchByUrlConnector.scala b/app/uk/gov/hmrc/cataloguefrontend/connector/SearchByUrlConnector.scala index 3ae2a1876..28ced1510 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/connector/SearchByUrlConnector.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/connector/SearchByUrlConnector.scala @@ -42,6 +42,7 @@ class SearchByUrlConnector @Inject() ( ( (__ \ "frontendPath" ).read[String] ~ (__ \ "ruleConfigurationUrl").readWithDefault[String]("") ~ (__ \ "isRegex" ).readWithDefault[Boolean](false) + ~ (__ \ "isDevhub" ).readWithDefault[Boolean](false) )(FrontendRoute.apply) private given Reads[FrontendRoutes] = diff --git a/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala b/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala index 0cc561032..39f224c80 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala @@ -17,74 +17,61 @@ package uk.gov.hmrc.cataloguefrontend.service import javax.inject.{Inject, Singleton} -import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName} +import uk.gov.hmrc.cataloguefrontend.model.Environment import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector -import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.EnvironmentRoute +import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} import uk.gov.hmrc.http.HeaderCarrier -import scala.concurrent.{ExecutionContext, Future} +import scala.concurrent.ExecutionContext -class RouteRulesService @Inject() ( - routeRulesConnector: RouteRulesConnector +class RouteRulesService @Inject()( )(using ExecutionContext): + import RouteRulesService._ - def serviceRoutes(serviceName: ServiceName)(using HeaderCarrier): Future[ServiceRoutes] = - for - frontendRoutes <- routeRulesConnector.frontendRoutes(serviceName) - adminRoutes <- routeRulesConnector.adminFrontendRoutes(serviceName) - yield ServiceRoutes(frontendRoutes ++ adminRoutes) + def serviceRoutes(routes: Seq[Route])(using HeaderCarrier): ServiceRoutes = + // exclude new Devhub route type for now + ServiceRoutes(routes.filterNot(_.routeType == RouteType.Devhub)) @Singleton object RouteRulesService: case class ServiceRoutes( - environmentRoutes: Seq[EnvironmentRoute] + routes: Seq[Route] ): - private val normalisedEvironmentRoutes: Seq[EnvironmentRoute] = // this should probably be a Map[Environment, Route] - we would need to move isAdmin onto the Route to remove EnvironmentRoute - environmentRoutes - .groupBy(_.environment) - .map: (env, routes) => - EnvironmentRoute( - environment = env - , routes = routes.flatMap(_.routes) - ) - .toSeq - private[service] val referenceEnvironmentRoutes: Option[EnvironmentRoute] = - normalisedEvironmentRoutes - .find(_.environment == Environment.Production) - .orElse(normalisedEvironmentRoutes.headOption) - .orElse(None) + private val envRoutes = + routes.groupBy(_.environment) + + private[service] val referenceRoutes: Seq[Route] = + envRoutes + .getOrElse( + Environment.Production, + envRoutes.values.headOption.getOrElse(Seq.empty) + ) - private def hasDifferentRoutesToReferenceEnvironment(environmentRoute: EnvironmentRoute, referenceEnvironmentRoute: EnvironmentRoute) = - environmentRoute.routes - .map(_.frontendPath) - .diff(referenceEnvironmentRoute.routes.map(_.frontendPath)) + private def hasDifferentPaths(envRoutes: Seq[Route], refRoutes: Seq[Route]): Boolean = + envRoutes + .map(_.path) + .diff(refRoutes.map(_.path)) .nonEmpty - private def filterRoutesToDifferences(environmentRoute: EnvironmentRoute, referenceEnvironmentRoute: EnvironmentRoute) = - environmentRoute.routes + private def filterDifferences(envRoutes: Seq[Route], refRoutes: Seq[Route]): Seq[Route] = + envRoutes .filter: r => - environmentRoute.routes - .map(_.frontendPath) - .diff(referenceEnvironmentRoute.routes.map(_.frontendPath)) - .contains(r.frontendPath) + envRoutes + .map(_.path) + .diff(refRoutes.map(_.path)) + .contains(r.path) - val inconsistentRoutes: Seq[EnvironmentRoute] = - referenceEnvironmentRoutes - .map: refEnvRoutes => - normalisedEvironmentRoutes - .filter(_.environment != refEnvRoutes.environment) - .filter(environmentRoute => hasDifferentRoutesToReferenceEnvironment(environmentRoute, refEnvRoutes)) - .map(environmentRoute => environmentRoute.copy(routes = filterRoutesToDifferences(environmentRoute, refEnvRoutes))) - .getOrElse(Nil) + val inconsistentRoutes: Seq[Route] = + envRoutes + .collect: + case (env, routes) if env != Environment.Production && hasDifferentPaths(routes, referenceRoutes) => + filterDifferences(routes, referenceRoutes) + .flatten + .toSeq val hasInconsistentRoutes: Boolean = inconsistentRoutes.nonEmpty - val isDefined: Boolean = - environmentRoutes.nonEmpty - - end ServiceRoutes - end RouteRulesService diff --git a/app/uk/gov/hmrc/cataloguefrontend/service/SearchByUrlService.scala b/app/uk/gov/hmrc/cataloguefrontend/service/SearchByUrlService.scala index df0f97e81..1a47c037a 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/service/SearchByUrlService.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/service/SearchByUrlService.scala @@ -38,9 +38,10 @@ class SearchByUrlService @Inject() ( )(using HeaderCarrier): Future[Seq[FrontendRoutes]] = if isValidSearchTerm(term) then - searchByUrlConnector - .search(takeUrlPath(term.get)) - .map(_.filter(_.environment == environment)) + searchByUrlConnector.search(takeUrlPath(term.get)).map: searchResults => + searchResults + .filter(_.environment == environment) + .map(r => r.copy(routes = r.routes.filterNot(_.isDevhub))) else Future.successful(Nil) @@ -81,7 +82,8 @@ object SearchByUrlService: case class FrontendRoute( frontendPath : String, ruleConfigurationUrl: String = "", - isRegex : Boolean = false + isRegex : Boolean = false, + isDevhub : Boolean = false, ) case class FrontendRoutes( diff --git a/app/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterService.scala b/app/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterService.scala index d5c297a54..ea34af643 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterService.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterService.scala @@ -17,7 +17,8 @@ package uk.gov.hmrc.cataloguefrontend.shuttering import cats.data.OptionT -import cats.implicits._ +import cats.implicits.* + import javax.inject.{Inject, Singleton} import uk.gov.hmrc.cataloguefrontend.connector.{GitHubProxyConnector, RouteRulesConnector} import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName} @@ -26,6 +27,7 @@ import uk.gov.hmrc.http.HeaderCarrier import scala.concurrent.{ExecutionContext, Future} import org.jsoup.nodes.Document +import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.RouteType @Singleton class ShutterService @Inject() ( @@ -110,11 +112,9 @@ class ShutterService @Inject() ( HeaderCarrier ): Future[Option[String]] = for - baseRoutes <- routeRulesConnector.frontendRoutes(serviceName) - yield - for - envRoute <- baseRoutes.find(_.environment == env).map(_.routes) - frontendRoute <- envRoute.find(_.isRegex == false) - yield ShutterLinkUtils.mkLink(env, frontendRoute.frontendPath) + frontendRoutes <- routeRulesConnector.routes(serviceName, Some(RouteType.Frontend), Some(env)) + shutterRoute = frontendRoutes.find(_.isRegex == false) + yield shutterRoute.map: r => + ShutterLinkUtils.mkLink(env, r.path) end ShutterService diff --git a/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html b/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html index 133fdda05..5462084b3 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html +++ b/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html @@ -19,6 +19,8 @@ @import uk.gov.hmrc.cataloguefrontend.prcommenter.PrCommenterReport @import uk.gov.hmrc.cataloguefrontend.cost.{CostEstimateConfig, ServiceCostEstimate} @import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService.ServiceRoutes +@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.Route +@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.RouteType @import uk.gov.hmrc.cataloguefrontend.servicecommissioningstatus.Lifecycle @import uk.gov.hmrc.cataloguefrontend.serviceconfigs.ServiceConfigsService @import uk.gov.hmrc.cataloguefrontend.view.ViewMessages @@ -37,6 +39,7 @@ repositoryCreationDate : Instant, envDatas : Map[SlugInfoFlag, EnvData], linkToLeakDetection : Option[String], + allRoutes : Seq[Route], serviceRoutes : ServiceRoutes, hasBranchProtectionAuth : EnableBranchProtection.HasAuthorisation, commenterReport : Option[PrCommenterReport], @@ -44,7 +47,7 @@ canMarkForDecommissioning : MarkForDecommissioning.HasAuthorisation, lifecycle : Option[Lifecycle], testJobMap : Map[String, Seq[JenkinsJob]], - isGuest : Boolean + isGuest : Boolean, )(implicit messages : Messages, request : RequestHeader, @@ -93,18 +96,10 @@

- @serviceRoutes.environmentRoutes.find(er => er.environment == Environment.Production && !er.isAdmin).map { envRoute => + @if(allRoutes.nonEmpty) {
- @partials.serviceUrlDetails(envRoute, isAdmin = false) -
-
- } - - @serviceRoutes.environmentRoutes.find(er => er.environment == Environment.Production && er.isAdmin).map { envRoute => -
-
- @partials.serviceUrlDetails(envRoute, isAdmin = true) + @partials.serviceUrlDetails(allRoutes)
} diff --git a/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceRouteRuleViolations.scala.html b/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceRouteRuleViolations.scala.html index 0d3f34b49..0f2475bc8 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceRouteRuleViolations.scala.html +++ b/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceRouteRuleViolations.scala.html @@ -30,17 +30,15 @@ Route Rule - @for(environmentRoute <- serviceRoutes.inconsistentRoutes) { - @for(route <- environmentRoute.routes) { + @for(route <- serviceRoutes.inconsistentRoutes) { - @environmentRoute.environment + @route.environment - @route.frontendPath + @route.path - } } diff --git a/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceUrlDetails.scala.html b/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceUrlDetails.scala.html index 56b1a4ae5..50d2cfd88 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceUrlDetails.scala.html +++ b/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceUrlDetails.scala.html @@ -14,34 +14,94 @@ * limitations under the License. *@ -@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.EnvironmentRoute +@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.Route +@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.RouteType -@(environmentRoute: EnvironmentRoute, - isAdmin : Boolean -) - -@defining(environmentRoute.routes.size > 4) { collapsable => -
-
-
@if(isAdmin) { Admin } Frontend Routing Configuration
-
-
-
-
-
    - @for((route, index) <- (environmentRoute.routes) .zipWithIndex) { -
  • - @route.frontendPath -
  • - } -
-
+@(routes: Seq[Route]) +
+
+
Routing Configuration
+
+
+
+ @routes.groupBy(_.routeType).map { (rt, routes) => + @if(routes.nonEmpty) { +
+
+
+ +
    + @routes.map { route => + @if(rt == RouteType.ApiContext) { +
  • @route.path
  • + } else { +
  • + + @route.path + + +
  • + } + } +
+
+
+
+ } + } +@* @if(routes.exists(_.routeType == RouteType.AdminFrontend)) {*@ +@*
*@ +@*
*@ +@*
*@ +@* *@ +@* *@ +@*
*@ +@*
*@ +@*
*@ +@* }*@ +@* @if(routes.exists(_.routeType == RouteType.Devhub)) {*@ +@*
*@ +@*
*@ +@*
*@ +@* *@ +@* *@ +@*
*@ +@*
*@ +@*
*@ +@* }*@ +@* @if(routes.exists(_.routeType == RouteType.ApiContext)) {*@ +@*
*@ +@*
*@ +@*
*@ +@* *@ +@*
    *@ +@* @routes.filter(_.routeType == RouteType.ApiContext).map { route =>*@ +@*
  • @route.path
  • *@ +@* }*@ +@*
*@ +@*
*@ +@*
*@ +@*
*@ +@* }*@
- @if(collapsable) { - - }
-} +
+ diff --git a/app/uk/gov/hmrc/cataloguefrontend/whatsrunningwhere/ReleasesConnector.scala b/app/uk/gov/hmrc/cataloguefrontend/whatsrunningwhere/ReleasesConnector.scala index a89cd0ec9..9939c9904 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/whatsrunningwhere/ReleasesConnector.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/whatsrunningwhere/ReleasesConnector.scala @@ -17,7 +17,8 @@ package uk.gov.hmrc.cataloguefrontend.whatsrunningwhere import play.api.Logger -import play.api.libs.json.Reads +import play.api.libs.functional.syntax.toFunctionalBuilderOps +import play.api.libs.json.{Reads, __} import uk.gov.hmrc.cataloguefrontend.util.DateHelper.{atEndOfDayInstant, atStartOfDayInstant} import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName} import uk.gov.hmrc.http.{HeaderCarrier, HttpReads, StringContextOps, UpstreamErrorResponse} @@ -128,5 +129,25 @@ class ReleasesConnector @Inject() ( logger.warn(s"Received 404 from API for timeline of service ${service.asString}") Map.empty[String, Seq[DeploymentTimelineEvent]] } + + private given Reads[ReleasesConnector.ApiService] = ReleasesConnector.apiServiceReads + + def apiServices(environment: Environment)(using HeaderCarrier): Future[Seq[ReleasesConnector.ApiService]] = + httpClientV2 + .get(url"$serviceUrl/releases-api/apis/${environment.asString}") + .execute[Seq[ReleasesConnector.ApiService]] end ReleasesConnector + +object ReleasesConnector: + final case class ApiService( + serviceName: ServiceName + , context : String + , environment: Environment + ) + + private val apiServiceReads: Reads[ApiService] = + ( (__ \ "serviceName").read[ServiceName] + ~ (__ \ "context" ).read[String] + ~ (__ \ "environment").read[Environment] + )(ApiService.apply _) diff --git a/test/uk/gov/hmrc/cataloguefrontend/ServicePageSpec.scala b/test/uk/gov/hmrc/cataloguefrontend/ServicePageSpec.scala index 8f556a8d5..d15406ee3 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/ServicePageSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/ServicePageSpec.scala @@ -36,7 +36,8 @@ class ServicePageSpec extends UnitSpec with FakeApplicationBuilder { setupAuthEndpoint() setupEnableBranchProtectionAuthEndpoint() serviceEndpoint(GET, "/reports/repositories", willRespondWith = (200, Some("[]"))) - serviceEndpoint(GET, "/service-configs/frontend-route/service-1", willRespondWith = (200, Some(JsonData.serviceConfigsServiceService1))) + serviceEndpoint(GET, "/service-configs/routes/service1", willRespondWith = (200, Some(JsonData.serviceConfigsServiceService1))) + serviceEndpoint(GET, "/releases-api/apis/production", willRespondWith = (200, Some(JsonData.releasesApiContext))) serviceEndpoint(GET, "/service-configs/frontend-route/service-name", willRespondWith = (200, Some(JsonData.serviceConfigsServiceService1))) serviceEndpoint(GET, "/api/repositories/service-1/module-dependencies?version=latest",willRespondWith = (200, Some("[]"))) serviceEndpoint(GET, "/api/repositories/service-1/module-dependencies?version=0.0.1", willRespondWith = (200, Some("[]"))) diff --git a/test/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnectorSpec.scala b/test/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnectorSpec.scala index 6c24b706a..911f209c1 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnectorSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnectorSpec.scala @@ -16,13 +16,13 @@ package uk.gov.hmrc.cataloguefrontend.connector -import com.github.tomakehurst.wiremock.client.WireMock._ +import com.github.tomakehurst.wiremock.client.WireMock.* import org.mockito.Mockito.when import org.scalatest.concurrent.{IntegrationPatience, ScalaFutures} import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import org.scalatestplus.mockito.MockitoSugar -import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName} +import uk.gov.hmrc.cataloguefrontend.model.ServiceName import uk.gov.hmrc.http.HeaderCarrier import uk.gov.hmrc.http.test.{HttpClientV2Support, WireMockSupport} import uk.gov.hmrc.play.bootstrap.config.ServicesConfig @@ -36,9 +36,9 @@ class RouteRulesConnectorSpec with ScalaFutures with IntegrationPatience with WireMockSupport - with HttpClientV2Support { + with HttpClientV2Support: - private trait Setup { + private trait Setup: val servicesConfig = mock[ServicesConfig] when(servicesConfig.baseUrl("service-configs")) .thenReturn(wireMockUrl) @@ -46,36 +46,38 @@ class RouteRulesConnectorSpec given HeaderCarrier = HeaderCarrier() given ExecutionContext = ExecutionContext.global val connector = RouteRulesConnector(httpClientV2, servicesConfig) - } + end Setup - "RouteRulesConnector.serviceRoutes" should { - "return service routes" in new Setup { + "RouteRulesConnector.serviceRoutes" should: + "return service routes" in new Setup: stubFor( - get(urlPathEqualTo("/service-configs/frontend-route/service1")) - .willReturn(aResponse().withBody("""[ - { "environment": "production", - "routes": [ - {"frontendPath": "fp", "ruleConfigurationUrl": "rcu", "isRegex": false} - ] - } - ]""")) + get(urlPathEqualTo("/service-configs/routes/service1")) + .willReturn( + aResponse() + .withBody( + """[ + {"path": "fp","ruleConfigurationUrl": "rcu","isRegex": false,"routeType": "frontend","environment": "production"} + ,{"path": "fp","ruleConfigurationUrl": "rcu","isRegex": false,"routeType": "adminfrontend","environment": "production"} + ]""" + ) + ) ) - import RouteRulesConnector.{EnvironmentRoute, Route} - connector.frontendRoutes(ServiceName("service1")).futureValue shouldBe Seq( - EnvironmentRoute( - environment = Environment.Production - , routes = Route( - frontendPath = "fp" - , ruleConfigurationUrl = "rcu" - , isRegex = false - ) :: Nil - , isAdmin = false - )) + import RouteRulesConnector.{Route, RouteType} + import uk.gov.hmrc.cataloguefrontend.model.Environment - wireMockServer.verify( - getRequestedFor(urlPathEqualTo("/service-configs/frontend-route/service1")) + connector.routes(ServiceName("service1")).futureValue shouldBe Seq( + Route( + path = "fp", + ruleConfigurationUrl = Some("rcu"), + routeType = RouteType.Frontend, + environment = Environment.Production + ), + Route( + path = "fp", + ruleConfigurationUrl = Some("rcu"), + routeType = RouteType.AdminFrontend, + environment = Environment.Production + ) ) - } - } -} +end RouteRulesConnectorSpec diff --git a/test/uk/gov/hmrc/cataloguefrontend/jsondata/JsonData.scala b/test/uk/gov/hmrc/cataloguefrontend/jsondata/JsonData.scala index dc666c336..94ddd04f8 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/jsondata/JsonData.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/jsondata/JsonData.scala @@ -247,39 +247,29 @@ object JsonData { "[]" val serviceConfigsServiceService1 = - """[ - { - "environment": "qa", - "routes": [ - { - "frontendPath": "/test/qa/ccc", - "ruleConfigurationUrl": "https://github.com/hmrc/mdtp-frontend-routes/blob/main/production/frontend-proxy-application-rules.conf#L29", - "isRegex": false - } - ] - }, - { - "environment": "production", - "routes": [ - { - "frontendPath": "/test/prod/ccc", - "ruleConfigurationUrl": "https://github.com/hmrc/mdtp-frontend-routes/blob/main/production/frontend-proxy-application-rules.conf#L29", - "isRegex": false - } - ] - }, - { - "environment": "development", - "routes": [ - { - "frontendPath": "/test/dev/ccc", - "ruleConfigurationUrl": "https://github.com/hmrc/mdtp-frontend-routes/blob/main/production/frontend-proxy-application-rules.conf#L29", - "isRegex": false - } - ] - } - ] - """ + """[ + { + "path": "/test/qa/ccc", + "ruleConfigurationUrl": "https://github.com/hmrc/mdtp-frontend-routes/blob/main/production/frontend-proxy-application-rules.conf#L29", + "isRegex": false, + "routeType": "frontend", + "environment": "qa" + }, + { + "path": "/test/prod/ccc", + "ruleConfigurationUrl": "https://github.com/hmrc/mdtp-frontend-routes/blob/main/production/frontend-proxy-application-rules.conf#L29", + "isRegex": false, + "routeType": "frontend", + "environment": "production" + }, + { + "path": "/test/dev/ccc", + "ruleConfigurationUrl": "https://github.com/hmrc/mdtp-frontend-routes/blob/main/production/frontend-proxy-application-rules.conf#L29", + "isRegex": false, + "routeType": "frontend", + "environment": "development" + } + ]""" val deploymentConfigsService1 = """[{"name": "test", "instances": 1, "slots": 1, "environment": "production", "zone": "protected"}]""" @@ -605,4 +595,16 @@ object JsonData { | "outboundServices": ["service-c", "service-d"] |} |""".stripMargin + + val releasesApiContext: String = + """[ + | { + | "serviceName": "service1", + | "context": "misc/service1", + | "version": "4.167.0", + | "environment": "production", + | "deploymentId": "edge-deployment-123", + | "awaitingApproval": false + | } + |]""".stripMargin } diff --git a/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala b/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala index 0fc34799e..a1d43b9da 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala @@ -18,8 +18,10 @@ package uk.gov.hmrc.cataloguefrontend.service import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec -import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{EnvironmentRoute, Route} +import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.RouteType.AdminFrontend +import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} import uk.gov.hmrc.cataloguefrontend.model.Environment +import uk.gov.hmrc.cataloguefrontend.model.Environment.QA import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService.ServiceRoutes class RouteRulesServiceSpec extends AnyWordSpec with Matchers { @@ -31,34 +33,30 @@ class RouteRulesServiceSpec extends AnyWordSpec with Matchers { } "determine if there is inconsistency in the public URL rules" in { - val environmentRoutes = Seq( - EnvironmentRoute(Environment.Production, Seq(Route("frontendPath", "ruleConfigurationUrl"))), - EnvironmentRoute(Environment.QA, - Seq( - Route("frontendPath", "ruleConfigurationUrlQa"), - Route("inconsistent", "ruleConfigurationUrlQa") - ) - ) + + val envRoutes = Seq( + Route("frontendPath", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.Production), + Route("frontendPath", Some("ruleConfigurationUrlQa"), false, RouteType.Frontend, Environment.QA ), + Route("inconsistent", Some("ruleConfigurationUrlQa"), false, RouteType.Frontend, Environment.QA ), ) - val inconsistentRoutes = ServiceRoutes(environmentRoutes).inconsistentRoutes - inconsistentRoutes.nonEmpty shouldBe true - inconsistentRoutes.head.environment shouldBe Environment.QA - inconsistentRoutes.head.routes.length shouldBe 1 - inconsistentRoutes.head.routes.head.frontendPath shouldBe "inconsistent" + val inconsistentRoutes = ServiceRoutes(envRoutes).inconsistentRoutes + inconsistentRoutes.nonEmpty shouldBe true + inconsistentRoutes.head.environment shouldBe Environment.QA + inconsistentRoutes.length shouldBe 1 + inconsistentRoutes.head.path shouldBe "inconsistent" } "determine if there is inconsistency with public URL rules when duplicates exist" in { val environmentRoutes = Seq( - EnvironmentRoute(Environment.Production, Seq( - Route("frontendPathOne", "ruleConfigurationUrlOne"), - Route("frontendPathTwo", "ruleConfigurationUrlTwo") - )), - EnvironmentRoute(Environment.QA, Seq( - Route("frontendPathOne", "ruleConfigurationUrlOne"), - Route("frontendPathTwo", "ruleConfigurationUrlTwo"), - Route("frontendPathTwo", "ruleConfigurationUrlTwo") - )) + + Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.Production), + Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.Production), + + Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.QA), + Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.QA), + Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.QA) + ) val inconsistentRoutes = ServiceRoutes(environmentRoutes).inconsistentRoutes @@ -68,124 +66,74 @@ class RouteRulesServiceSpec extends AnyWordSpec with Matchers { "determine if there is consistency with public URL rules" in { val environmentRoutes = Seq( - EnvironmentRoute(Environment.Production, Seq( - Route("frontendPathOne", "ruleConfigurationUrlOne"), - Route("frontendPathTwo", "ruleConfigurationUrlTwo") - )), - EnvironmentRoute(Environment.QA, Seq( - Route("frontendPathOne", "ruleConfigurationUrlOne"), - Route("frontendPathTwo", "ruleConfigurationUrlTwo") - )) + Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.Production), + Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.Production), + + Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.QA ), + Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.QA ) ) ServiceRoutes(environmentRoutes).inconsistentRoutes.nonEmpty shouldBe false } - "be consistent when no routes" in { - val environmentRoutes = Seq( - EnvironmentRoute(Environment.Production, Seq.empty), - EnvironmentRoute(Environment.QA , Seq.empty) + "determine if there is inconsistency in the URL paths" in { + val routes = Seq( + Route("frontendPath", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.Production), + Route("frontendPath", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA ), + Route("inconsistent", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA ), ) + val inconsistentRoutes = ServiceRoutes(routes).inconsistentRoutes + inconsistentRoutes shouldBe Seq( + Route("inconsistent", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA) + ) + } + + "be consistent when no routes" in { + val environmentRoutes = Seq.empty[Route] + ServiceRoutes(environmentRoutes).inconsistentRoutes.nonEmpty shouldBe false } "return Production environment route as default reference route" in { val environmentRoutes = Seq( - EnvironmentRoute(Environment.Production, Seq(Route("frontendPath", "ruleConfigurationUrl"))), - EnvironmentRoute(Environment.QA , Seq(Route("inconsistent", "ruleConfigurationUrl"))) + Route("frontendPath", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.Production), + Route("inconsistent", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA ), ) - ServiceRoutes(environmentRoutes).referenceEnvironmentRoutes.isDefined shouldBe true + ServiceRoutes(environmentRoutes).referenceRoutes.nonEmpty shouldBe true + ServiceRoutes(environmentRoutes).referenceRoutes.head.environment shouldBe Environment.Production } "return next environment route as reference when no production" in { val environmentRoutes = Seq( - EnvironmentRoute(Environment.Development, Seq(Route("frontendPath", "ruleConfigurationUrl"))), - EnvironmentRoute(Environment.QA , Seq(Route("inconsistent", "ruleConfigurationUrl"))) + Route("frontendPath", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.Development), + Route("inconsistent", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA ), ) - ServiceRoutes(environmentRoutes).referenceEnvironmentRoutes.isDefined shouldBe true + ServiceRoutes(environmentRoutes).referenceRoutes.nonEmpty shouldBe true } "return no reference environment when no environment routes" in { - val environmentRoutes: Seq[EnvironmentRoute] = Nil + val environmentRoutes: Seq[Route] = Seq.empty - ServiceRoutes(environmentRoutes).referenceEnvironmentRoutes.isDefined shouldBe false + ServiceRoutes(environmentRoutes).referenceRoutes.isEmpty shouldBe true } "handle Admin and Frontend routes" in { + val adminRoutes = Seq( - EnvironmentRoute( - environment = Environment.QA, - routes = Seq(Route( - frontendPath = "/fh-admin-page", - ruleConfigurationUrl = "", - isRegex = false - )), - isAdmin = true - ), - EnvironmentRoute( - environment = Environment.Production, - routes = Seq(Route( - frontendPath = "/fh-admin-page", - ruleConfigurationUrl = "", - isRegex = false - )), - isAdmin = true - ), - EnvironmentRoute( - environment = Environment.Staging, - routes = Seq(Route( - frontendPath = "/fh-admin-page", - ruleConfigurationUrl = "", - isRegex = false - )), - isAdmin = true - )) + Route("/fh/admin-page", Some(""), false, RouteType.AdminFrontend, Environment.QA ), + Route("/fh/admin-page", Some(""), false, RouteType.AdminFrontend, Environment.Production), + Route("/fh/admin-page", Some(""), false, RouteType.AdminFrontend, Environment.Staging ), + ) val frontendRoutes = Seq( - EnvironmentRoute( - environment = Environment.QA, - routes = Seq(Route( - frontendPath = "/fhdds", - ruleConfigurationUrl = "", - isRegex = false - )), - isAdmin = false - ), - EnvironmentRoute( - environment = Environment.Staging, - routes = Seq(Route( - frontendPath = "/fhdds", - ruleConfigurationUrl = "", - isRegex = false - )), - ), - EnvironmentRoute( - environment = Environment.Production, - routes = Seq(Route( - frontendPath = "/fhdds", - ruleConfigurationUrl = "", - isRegex = false - )), - ), - EnvironmentRoute( - environment = Environment.Integration, - routes = Seq(Route( - frontendPath = "/fhdds", - ruleConfigurationUrl = "", - isRegex = false - )), - ), - EnvironmentRoute( - environment = Environment.Development, - routes = Seq(Route( - frontendPath = "/fhdds", - ruleConfigurationUrl = "", - isRegex = false - )) - ) + Route("/fhdds", Some(""), false, RouteType.Frontend, Environment.QA ), + Route("/fhdds", Some(""), false, RouteType.Frontend, Environment.Staging ), + Route("/fhdds", Some(""), false, RouteType.Frontend, Environment.Production ), + Route("/fhdds", Some(""), false, RouteType.Frontend, Environment.Integration), + Route("/fhdds", Some(""), false, RouteType.Frontend, Environment.Development), ) val inconsistentRoutes = ServiceRoutes(adminRoutes ++ frontendRoutes).inconsistentRoutes diff --git a/test/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterServiceSpec.scala b/test/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterServiceSpec.scala index 9c371eb14..1e739b290 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterServiceSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterServiceSpec.scala @@ -21,6 +21,8 @@ import org.scalatest.concurrent.{IntegrationPatience, ScalaFutures} import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import org.scalatestplus.mockito.MockitoSugar +import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} +import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.RouteType.Frontend import uk.gov.hmrc.cataloguefrontend.connector.{GitHubProxyConnector, RouteRulesConnector} import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName, UserName} import uk.gov.hmrc.http.HeaderCarrier @@ -110,6 +112,25 @@ class ShutterServiceSpec } } + "lookupShutterRoute" should { + "return a frontend route that is not regex" in { + val boot = Boot.init + given HeaderCarrier = HeaderCarrier() + + val serviceName = ServiceName("service1") + val env = Environment.Production + + when(boot.mockRouteRulesConnector.routes(serviceName, Some(RouteType.Frontend), Some(env))) + .thenReturn(Future.successful(Seq( + Route("/path1", Some(""), isRegex = false, RouteType.Frontend, Environment.Production), + Route("/path2", Some(""), isRegex = true , RouteType.Frontend, Environment.Production) + ))) + + val shutterRoute = boot.shutterService.lookupShutterRoute(serviceName, env) + shutterRoute.futureValue shouldBe Some("https://www.tax.service.gov.uk/path1/platops-shutter-testing") + } + } + def mkOutagePage(serviceName: ServiceName, warnings: List[OutagePageWarning]): OutagePage = OutagePage( serviceName = serviceName @@ -120,15 +141,15 @@ class ShutterServiceSpec , templatedElements = List.empty ) - case class Boot(shutterService: ShutterService, mockShutterConnector: ShutterConnector) + case class Boot(shutterService: ShutterService, mockShutterConnector: ShutterConnector, mockRouteRulesConnector: RouteRulesConnector) object Boot { def init: Boot = val mockShutterConnector = mock[ShutterConnector] val mockShutterGroupsConnector = mock[ShutterGroupsConnector] - val routeRulesConnector = mock[RouteRulesConnector] + val mockRouteRulesConnector = mock[RouteRulesConnector] val mockGithubProxyConnector = mock[GitHubProxyConnector] - val shutterService = ShutterService(mockShutterConnector, mockShutterGroupsConnector, routeRulesConnector, mockGithubProxyConnector) - Boot(shutterService, mockShutterConnector) + val shutterService = ShutterService(mockShutterConnector, mockShutterGroupsConnector, mockRouteRulesConnector, mockGithubProxyConnector) + Boot(shutterService, mockShutterConnector, mockRouteRulesConnector) } } diff --git a/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/DetailsSpec.scala b/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/DetailsSpec.scala index da1af82e2..ef1e18730 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/DetailsSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/DetailsSpec.scala @@ -20,8 +20,7 @@ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import play.api.test.FakeRequest import uk.gov.hmrc.cataloguefrontend.cost.Zone -import uk.gov.hmrc.cataloguefrontend.connector.{GitRepository, RepoType, RouteRulesConnector, ServiceType} -import uk.gov.hmrc.cataloguefrontend.model.Environment +import uk.gov.hmrc.cataloguefrontend.connector.{GitRepository, RepoType, ServiceType} import java.time.Instant @@ -46,11 +45,6 @@ class DetailsSpec extends AnyWordSpec with Matchers { val repoWithDigitalServiceGrouping = repo.copy(digitalServiceName = Some("Digital Service Name")) - val environmentRoute = RouteRulesConnector.EnvironmentRoute( - environment = Environment.Production, - routes = Seq(RouteRulesConnector.Route("TestUrl0", "ruleConfigurationUrl0"), - RouteRulesConnector.Route("TestUrl1", "ruleConfigurationUrl1")) - ) private val request = FakeRequest() "details" should { diff --git a/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala b/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala index 3cd356b36..6f0b364ed 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala @@ -16,45 +16,45 @@ package uk.gov.hmrc.cataloguefrontend.view.partials.html -import org.scalatest.matchers.should.Matchers -import org.scalatest.wordspec.AnyWordSpec -import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{EnvironmentRoute, Route} -import uk.gov.hmrc.cataloguefrontend.model.Environment -import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService.ServiceRoutes - -class ServiceRouteRuleViolationsSpec extends AnyWordSpec with Matchers { - - val misMatchedServiceRoutes = ServiceRoutes(Seq( - EnvironmentRoute( - environment = Environment.Development, - routes = Seq(Route("TestUrl0", "ruleConfigurationUrl0")) - ), - EnvironmentRoute( - environment = Environment.Production, - routes = Seq(Route("TestUrl1", "ruleConfigurationUrl1")) - ) - )) - - val matchingServiceRoutes = ServiceRoutes(Seq( - EnvironmentRoute( - environment = Environment.Development, - routes = Seq(Route("TestUrl0", "ruleConfigurationUrl0")) - ), - EnvironmentRoute( - environment = Environment.Production, - routes = Seq(Route("TestUrl0", "ruleConfigurationUrl1")) - ) - )) - - "ServiceRouteRuleViolations" should { - "display when there are URLs not matching" in { - val result = serviceRouteRuleViolations(misMatchedServiceRoutes).body - result should include ("id=\"routing-rule-violations\"") - } - - "do not display when there are URLs are matching" in { - val result = serviceRouteRuleViolations(matchingServiceRoutes).body - result should not include ("id=\"routing-rule-violations\"") - } - } -} +//import org.scalatest.matchers.should.Matchers +//import org.scalatest.wordspec.AnyWordSpec +//import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{EnvironmentRoute, Route} +//import uk.gov.hmrc.cataloguefrontend.model.Environment +//import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService.ServiceRoutes +// +//class ServiceRouteRuleViolationsSpec extends AnyWordSpec with Matchers { +// +// val misMatchedServiceRoutes = ServiceRoutes(Seq( +// EnvironmentRoute( +// environment = Environment.Development, +// routes = Seq(Route("TestUrl0", "ruleConfigurationUrl0")) +// ), +// EnvironmentRoute( +// environment = Environment.Production, +// routes = Seq(Route("TestUrl1", "ruleConfigurationUrl1")) +// ) +// )) +// +// val matchingServiceRoutes = ServiceRoutes(Seq( +// EnvironmentRoute( +// environment = Environment.Development, +// routes = Seq(Route("TestUrl0", "ruleConfigurationUrl0")) +// ), +// EnvironmentRoute( +// environment = Environment.Production, +// routes = Seq(Route("TestUrl0", "ruleConfigurationUrl1")) +// ) +// )) +// +// "ServiceRouteRuleViolations" should { +// "display when there are URLs not matching" in { +// val result = serviceRouteRuleViolations(misMatchedServiceRoutes).body +// result should include ("id=\"routing-rule-violations\"") +// } +// +// "do not display when there are URLs are matching" in { +// val result = serviceRouteRuleViolations(matchingServiceRoutes).body +// result should not include ("id=\"routing-rule-violations\"") +// } +// } +//} From b30315c4cb29589f12300b86c8d941293739c39b Mon Sep 17 00:00:00 2001 From: Sam Sloman Date: Mon, 7 Oct 2024 17:19:05 +0100 Subject: [PATCH 2/5] BDOG-3206: refactor to remove mistakes --- .../CatalogueController.scala | 6 +- .../connector/RouteRulesConnector.scala | 39 ---------- .../view/ServiceInfoPage.scala.html | 2 +- .../html/ServiceRouteRuleViolationsSpec.scala | 73 ++++++++----------- 4 files changed, 35 insertions(+), 85 deletions(-) diff --git a/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala b/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala index 437fbe5cf..56827d94e 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala @@ -210,7 +210,7 @@ class CatalogueController @Inject() ( environment = api.environment ) allRoutes = (routes ++ apiRoutes).filter(_.environment == Environment.Production) - inconsistentRoutesCheck = routeRulesService.serviceRoutes(routes) + inconsistentRoutes = routeRulesService.serviceRoutes(routes) optLatestServiceInfo <- serviceDependenciesConnector.getSlugInfo(serviceName) serviceCostEstimate <- costEstimationService.estimateServiceCost(serviceName) commenterReport <- prCommenterConnector.report(repositoryName) @@ -242,14 +242,14 @@ class CatalogueController @Inject() ( envDatas = optLatestData.fold(envDatas)(envDatas + _), linkToLeakDetection = urlIfLeaksFound, allRoutes = allRoutes, - serviceRoutes = inconsistentRoutesCheck, + serviceRoutes = inconsistentRoutes, hasBranchProtectionAuth = hasBranchProtectionAuth, commenterReport = commenterReport, serviceRelationships = serviceRelationships, canMarkForDecommissioning = canMarkForDecommissioning, lifecycle = lifecycle, testJobMap = testJobMap, - isGuest = isGuest, + isGuest = isGuest )) def library(name: String): Action[AnyContent] = diff --git a/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala b/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala index 71fa94efa..0c59d76fc 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala @@ -66,45 +66,6 @@ class RouteRulesConnector @Inject() ( logger.error(s"An error occurred when connecting to $url: ${ex.getMessage}", ex) Seq.empty -// // Used by ShutterService, replace with query param for Frontend Routes only -// def frontendRoutes(service: ServiceName)(using HeaderCarrier): Future[Seq[EnvironmentRoute]] = -// val url = url"$baseUrl/service-configs/frontend-route/${service.asString}" -// given Reads[EnvironmentRoute] = EnvironmentRoute.reads -// httpClientV2 -// .get(url) -// .execute[Seq[EnvironmentRoute]] -// .recover: -// case NonFatal(ex) => -// logger.error(s"An error occurred when connecting to $url: ${ex.getMessage}", ex) -// Seq.empty - -// def adminFrontendRoutes(service: ServiceName)(using HeaderCarrier): Future[Seq[EnvironmentRoute]] = -// val url = url"$baseUrl/service-configs/admin-frontend-route/${service.asString}" -// given Reads[AdminFrontendRoute] = AdminFrontendRoute.reads -// httpClientV2 -// .get(url) -// .execute[Seq[AdminFrontendRoute]] -// .map: -// _ -// .flatMap: raw => -// raw.allow.keys.map: env => -// EnvironmentRoute( -// environment = env -// , routes = Seq(Route( -// frontendPath = raw.route -// , ruleConfigurationUrl = raw.location -// , isRegex = false -// )) -// ) -// .groupBy(_.environment) -// .toSeq -// .map: (k, v) => -// EnvironmentRoute(k, v.flatMap(_.routes.sortBy(_.ruleConfigurationUrl)), isAdmin = true) -// .recover: -// case NonFatal(ex) => -// logger.error(s"An error occurred when connecting to $url: ${ex.getMessage}", ex) -// Seq.empty - object RouteRulesConnector: import uk.gov.hmrc.cataloguefrontend.util.{FromString, FromStringEnum, Parser} import FromStringEnum._ diff --git a/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html b/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html index 5462084b3..11adca94a 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html +++ b/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html @@ -47,7 +47,7 @@ canMarkForDecommissioning : MarkForDecommissioning.HasAuthorisation, lifecycle : Option[Lifecycle], testJobMap : Map[String, Seq[JenkinsJob]], - isGuest : Boolean, + isGuest : Boolean )(implicit messages : Messages, request : RequestHeader, diff --git a/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala b/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala index 6f0b364ed..4a47333dc 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala @@ -16,45 +16,34 @@ package uk.gov.hmrc.cataloguefrontend.view.partials.html -//import org.scalatest.matchers.should.Matchers -//import org.scalatest.wordspec.AnyWordSpec -//import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{EnvironmentRoute, Route} -//import uk.gov.hmrc.cataloguefrontend.model.Environment -//import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService.ServiceRoutes -// -//class ServiceRouteRuleViolationsSpec extends AnyWordSpec with Matchers { -// -// val misMatchedServiceRoutes = ServiceRoutes(Seq( -// EnvironmentRoute( -// environment = Environment.Development, -// routes = Seq(Route("TestUrl0", "ruleConfigurationUrl0")) -// ), -// EnvironmentRoute( -// environment = Environment.Production, -// routes = Seq(Route("TestUrl1", "ruleConfigurationUrl1")) -// ) -// )) -// -// val matchingServiceRoutes = ServiceRoutes(Seq( -// EnvironmentRoute( -// environment = Environment.Development, -// routes = Seq(Route("TestUrl0", "ruleConfigurationUrl0")) -// ), -// EnvironmentRoute( -// environment = Environment.Production, -// routes = Seq(Route("TestUrl0", "ruleConfigurationUrl1")) -// ) -// )) -// -// "ServiceRouteRuleViolations" should { -// "display when there are URLs not matching" in { -// val result = serviceRouteRuleViolations(misMatchedServiceRoutes).body -// result should include ("id=\"routing-rule-violations\"") -// } -// -// "do not display when there are URLs are matching" in { -// val result = serviceRouteRuleViolations(matchingServiceRoutes).body -// result should not include ("id=\"routing-rule-violations\"") -// } -// } -//} +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpec +import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} +import uk.gov.hmrc.cataloguefrontend.model.Environment +import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService.ServiceRoutes + +class ServiceRouteRuleViolationsSpec extends AnyWordSpec with Matchers { + + val misMatchedServiceRoutes = ServiceRoutes(Seq( + Route("TestUrl0", Some("ruleConfigurationUrl0"), false, RouteType.Frontend, Environment.Development), + Route("TestUrl1", Some("ruleConfigurationUrl1"), false, RouteType.Frontend, Environment.Production ) + )) + + + val matchingServiceRoutes = ServiceRoutes(Seq( + Route("TestUrl0", Some("ruleConfigurationUrl0"), false, RouteType.Frontend, Environment.Development), + Route("TestUrl0", Some("ruleConfigurationUrl1"), false, RouteType.Frontend, Environment.Production) + )) + + "ServiceRouteRuleViolations" should { + "display when there are URLs not matching" in { + val result = serviceRouteRuleViolations(misMatchedServiceRoutes).body + result should include ("id=\"routing-rule-violations\"") + } + + "do not display when there are URLs are matching" in { + val result = serviceRouteRuleViolations(matchingServiceRoutes).body + result should not include ("id=\"routing-rule-violations\"") + } + } +} From f7b19dca6c2650e579d8fb6d215abd9eb3e973e1 Mon Sep 17 00:00:00 2001 From: Sam Sloman Date: Tue, 8 Oct 2024 15:30:28 +0100 Subject: [PATCH 3/5] BDOG-3206: pr changes --- .../CatalogueController.scala | 11 ++-- .../connector/RouteRulesConnector.scala | 2 +- .../view/ServiceInfoPage.scala.html | 6 +-- .../partials/serviceUrlDetails.scala.html | 52 ------------------- 4 files changed, 10 insertions(+), 61 deletions(-) diff --git a/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala b/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala index c3c155826..ff7be8e81 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala @@ -197,9 +197,9 @@ class CatalogueController @Inject() ( .map(_.collect { case Some(v) => v }.toMap) latestRepoModules <- serviceDependenciesConnector.getRepositoryModulesLatestVersion(repositoryName) urlIfLeaksFound <- leakDetectionService.urlIfLeaksFound(repositoryName) - routes <- routesRulesConnector.routes(serviceName) + prodRoutes <- routesRulesConnector.routes(serviceName, None, Some(Environment.Production)) prodApiServices <- releasesConnector.apiServices(Environment.Production) - apiRoutes = prodApiServices.collect: + prodApiRoutes = prodApiServices.collect: case api if api.serviceName == serviceName => Route( path = api.context, @@ -207,8 +207,9 @@ class CatalogueController @Inject() ( routeType = RouteType.ApiContext, environment = api.environment ) - allRoutes = (routes ++ apiRoutes).filter(_.environment == Environment.Production) - inconsistentRoutes = routeRulesService.serviceRoutes(routes) + allProdRoutes = prodRoutes ++ prodApiRoutes + allRoutes <- routesRulesConnector.routes(serviceName) + inconsistentRoutes = routeRulesService.serviceRoutes(allRoutes) optLatestServiceInfo <- serviceDependenciesConnector.getSlugInfo(serviceName) serviceCostEstimate <- costEstimationService.estimateServiceCost(serviceName) commenterReport <- prCommenterConnector.report(repositoryName) @@ -239,7 +240,7 @@ class CatalogueController @Inject() ( repositoryCreationDate = repositoryDetails.createdDate, envDatas = optLatestData.fold(envDatas)(envDatas + _), linkToLeakDetection = urlIfLeaksFound, - allRoutes = allRoutes, + prodRoutes = allProdRoutes, serviceRoutes = inconsistentRoutes, hasBranchProtectionAuth = hasBranchProtectionAuth, commenterReport = commenterReport, diff --git a/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala b/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala index 0c59d76fc..38f7f7841 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala @@ -47,7 +47,7 @@ class RouteRulesConnector @Inject() ( )(using HeaderCarrier ): Future[Seq[Route]] = - val url = url"$baseUrl/service-configs/routes/${service.asString}" + val url = url"$baseUrl/service-configs/routes/${service.asString}?routeType=${routeType.map(_.asString)}&environment=${environment.map(_.asString)}" given Reads[Route] = Route.reads httpClientV2 .get(url) diff --git a/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html b/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html index 11adca94a..096f4bfb5 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html +++ b/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html @@ -39,7 +39,7 @@ repositoryCreationDate : Instant, envDatas : Map[SlugInfoFlag, EnvData], linkToLeakDetection : Option[String], - allRoutes : Seq[Route], + prodRoutes : Seq[Route], serviceRoutes : ServiceRoutes, hasBranchProtectionAuth : EnableBranchProtection.HasAuthorisation, commenterReport : Option[PrCommenterReport], @@ -96,10 +96,10 @@

- @if(allRoutes.nonEmpty) { + @if(prodRoutes.nonEmpty) {
- @partials.serviceUrlDetails(allRoutes) + @partials.serviceUrlDetails(prodRoutes)
} diff --git a/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceUrlDetails.scala.html b/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceUrlDetails.scala.html index 50d2cfd88..cec9acda8 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceUrlDetails.scala.html +++ b/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceUrlDetails.scala.html @@ -49,58 +49,6 @@ } } -@* @if(routes.exists(_.routeType == RouteType.AdminFrontend)) {*@ -@*
*@ -@*
*@ -@*
*@ -@* *@ -@* *@ -@*
*@ -@*
*@ -@*
*@ -@* }*@ -@* @if(routes.exists(_.routeType == RouteType.Devhub)) {*@ -@*
*@ -@*
*@ -@*
*@ -@* *@ -@* *@ -@*
*@ -@*
*@ -@*
*@ -@* }*@ -@* @if(routes.exists(_.routeType == RouteType.ApiContext)) {*@ -@*
*@ -@*
*@ -@*
*@ -@* *@ -@*
    *@ -@* @routes.filter(_.routeType == RouteType.ApiContext).map { route =>*@ -@*
  • @route.path
  • *@ -@* }*@ -@*
*@ -@*
*@ -@*
*@ -@*
*@ -@* }*@ From ea743da36943352d78de8242356ce4e7f209aa36 Mon Sep 17 00:00:00 2001 From: colin-lamed <9568290+colin-lamed@users.noreply.github.com> Date: Tue, 8 Oct 2024 12:56:46 +0100 Subject: [PATCH 4/5] BDOG-3206 Refactor inconsistent rules calculation --- .../service/RouteRulesService.scala | 47 +++++++--------- .../service/RouteRulesServiceSpec.scala | 53 ++++--------------- 2 files changed, 29 insertions(+), 71 deletions(-) diff --git a/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala b/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala index 39f224c80..30375ce31 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala @@ -24,50 +24,41 @@ import uk.gov.hmrc.http.HeaderCarrier import scala.concurrent.ExecutionContext +@Singleton class RouteRulesService @Inject()( )(using ExecutionContext): import RouteRulesService._ + // TODO replace with + // def inconsistentRoutes(routes: Seq[Route])(using HeaderCarrier): Seq[Route] = + def serviceRoutes(routes: Seq[Route])(using HeaderCarrier): ServiceRoutes = // exclude new Devhub route type for now ServiceRoutes(routes.filterNot(_.routeType == RouteType.Devhub)) -@Singleton + object RouteRulesService: case class ServiceRoutes( routes: Seq[Route] ): - private val envRoutes = - routes.groupBy(_.environment) + private val referenceRoutes: Seq[Route] = + for + referenceEnv <- routes.map(_.environment).sorted.reverse.headOption.toSeq + routes <- routes.filter(_.environment == referenceEnv) + yield routes - private[service] val referenceRoutes: Seq[Route] = - envRoutes - .getOrElse( - Environment.Production, - envRoutes.values.headOption.getOrElse(Seq.empty) - ) - - private def hasDifferentPaths(envRoutes: Seq[Route], refRoutes: Seq[Route]): Boolean = - envRoutes - .map(_.path) - .diff(refRoutes.map(_.path)) - .nonEmpty - - private def filterDifferences(envRoutes: Seq[Route], refRoutes: Seq[Route]): Seq[Route] = - envRoutes - .filter: r => - envRoutes - .map(_.path) - .diff(refRoutes.map(_.path)) - .contains(r.path) - - val inconsistentRoutes: Seq[Route] = - envRoutes + val inconsistentRoutes = + routes.groupBy(_.environment) .collect: - case (env, routes) if env != Environment.Production && hasDifferentPaths(routes, referenceRoutes) => - filterDifferences(routes, referenceRoutes) + case (_, envRoutes) => + val differentPaths = + envRoutes + .map(_.path) + .diff(referenceRoutes.map(_.path)) + envRoutes.filter: r => + differentPaths.contains(r.path) .flatten .toSeq diff --git a/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala b/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala index a1d43b9da..9b39eaac5 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala @@ -18,13 +18,11 @@ package uk.gov.hmrc.cataloguefrontend.service import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec -import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.RouteType.AdminFrontend import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} import uk.gov.hmrc.cataloguefrontend.model.Environment -import uk.gov.hmrc.cataloguefrontend.model.Environment.QA import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService.ServiceRoutes -class RouteRulesServiceSpec extends AnyWordSpec with Matchers { +class RouteRulesServiceSpec extends AnyWordSpec with Matchers: "Service" should { "return no result for inconsistency check when no environment routes" in { @@ -33,11 +31,10 @@ class RouteRulesServiceSpec extends AnyWordSpec with Matchers { } "determine if there is inconsistency in the public URL rules" in { - val envRoutes = Seq( Route("frontendPath", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.Production), Route("frontendPath", Some("ruleConfigurationUrlQa"), false, RouteType.Frontend, Environment.QA ), - Route("inconsistent", Some("ruleConfigurationUrlQa"), false, RouteType.Frontend, Environment.QA ), + Route("inconsistent", Some("ruleConfigurationUrlQa"), false, RouteType.Frontend, Environment.QA ) ) val inconsistentRoutes = ServiceRoutes(envRoutes).inconsistentRoutes @@ -49,14 +46,11 @@ class RouteRulesServiceSpec extends AnyWordSpec with Matchers { "determine if there is inconsistency with public URL rules when duplicates exist" in { val environmentRoutes = Seq( - - Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.Production), - Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.Production), - - Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.QA), - Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.QA), - Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.QA) - + Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.Production), + Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.Production), + Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.QA), + Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.QA), + Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.QA) ) val inconsistentRoutes = ServiceRoutes(environmentRoutes).inconsistentRoutes @@ -80,7 +74,7 @@ class RouteRulesServiceSpec extends AnyWordSpec with Matchers { val routes = Seq( Route("frontendPath", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.Production), Route("frontendPath", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA ), - Route("inconsistent", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA ), + Route("inconsistent", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA ) ) val inconsistentRoutes = ServiceRoutes(routes).inconsistentRoutes @@ -95,37 +89,11 @@ class RouteRulesServiceSpec extends AnyWordSpec with Matchers { ServiceRoutes(environmentRoutes).inconsistentRoutes.nonEmpty shouldBe false } - "return Production environment route as default reference route" in { - val environmentRoutes = Seq( - Route("frontendPath", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.Production), - Route("inconsistent", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA ), - ) - - ServiceRoutes(environmentRoutes).referenceRoutes.nonEmpty shouldBe true - ServiceRoutes(environmentRoutes).referenceRoutes.head.environment shouldBe Environment.Production - } - - "return next environment route as reference when no production" in { - val environmentRoutes = Seq( - Route("frontendPath", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.Development), - Route("inconsistent", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA ), - ) - - ServiceRoutes(environmentRoutes).referenceRoutes.nonEmpty shouldBe true - } - - "return no reference environment when no environment routes" in { - val environmentRoutes: Seq[Route] = Seq.empty - - ServiceRoutes(environmentRoutes).referenceRoutes.isEmpty shouldBe true - } - "handle Admin and Frontend routes" in { - val adminRoutes = Seq( Route("/fh/admin-page", Some(""), false, RouteType.AdminFrontend, Environment.QA ), Route("/fh/admin-page", Some(""), false, RouteType.AdminFrontend, Environment.Production), - Route("/fh/admin-page", Some(""), false, RouteType.AdminFrontend, Environment.Staging ), + Route("/fh/admin-page", Some(""), false, RouteType.AdminFrontend, Environment.Staging ) ) val frontendRoutes = Seq( @@ -133,7 +101,7 @@ class RouteRulesServiceSpec extends AnyWordSpec with Matchers { Route("/fhdds", Some(""), false, RouteType.Frontend, Environment.Staging ), Route("/fhdds", Some(""), false, RouteType.Frontend, Environment.Production ), Route("/fhdds", Some(""), false, RouteType.Frontend, Environment.Integration), - Route("/fhdds", Some(""), false, RouteType.Frontend, Environment.Development), + Route("/fhdds", Some(""), false, RouteType.Frontend, Environment.Development) ) val inconsistentRoutes = ServiceRoutes(adminRoutes ++ frontendRoutes).inconsistentRoutes @@ -141,4 +109,3 @@ class RouteRulesServiceSpec extends AnyWordSpec with Matchers { inconsistentRoutes.nonEmpty shouldBe false } } -} From a1f07188f8a64681e8d70f29c932014ab23cb35a Mon Sep 17 00:00:00 2001 From: Sam Sloman Date: Wed, 9 Oct 2024 08:29:07 +0100 Subject: [PATCH 5/5] BDOG-3026: refactors route rules service --- .../CatalogueController.scala | 28 +++++----- .../connector/RouteRulesConnector.scala | 2 +- .../service/RouteRulesService.scala | 54 ++++++------------- .../shuttering/ShutterService.scala | 2 +- .../view/ServiceInfoPage.scala.html | 10 ++-- .../serviceRouteRuleViolations.scala.html | 8 +-- .../partials/serviceUrlDetails.scala.html | 3 +- .../service/RouteRulesServiceSpec.scala | 38 +++++++------ .../shuttering/ShutterServiceSpec.scala | 1 - .../html/ServiceRouteRuleViolationsSpec.scala | 22 ++++---- 10 files changed, 73 insertions(+), 95 deletions(-) diff --git a/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala b/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala index ff7be8e81..29e764f9b 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala @@ -31,7 +31,6 @@ import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, Route import uk.gov.hmrc.cataloguefrontend.connector.model.RepositoryModules import uk.gov.hmrc.cataloguefrontend.cost.{CostEstimateConfig, CostEstimationService, Zone} import uk.gov.hmrc.cataloguefrontend.leakdetection.LeakDetectionService -import uk.gov.hmrc.cataloguefrontend.model.Environment.Production import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName, SlugInfoFlag, TeamName, Version} import uk.gov.hmrc.cataloguefrontend.prcommenter.PrCommenterConnector import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService @@ -197,19 +196,18 @@ class CatalogueController @Inject() ( .map(_.collect { case Some(v) => v }.toMap) latestRepoModules <- serviceDependenciesConnector.getRepositoryModulesLatestVersion(repositoryName) urlIfLeaksFound <- leakDetectionService.urlIfLeaksFound(repositoryName) - prodRoutes <- routesRulesConnector.routes(serviceName, None, Some(Environment.Production)) - prodApiServices <- releasesConnector.apiServices(Environment.Production) - prodApiRoutes = prodApiServices.collect: - case api if api.serviceName == serviceName => - Route( - path = api.context, - ruleConfigurationUrl = None, - routeType = RouteType.ApiContext, - environment = api.environment - ) - allProdRoutes = prodRoutes ++ prodApiRoutes - allRoutes <- routesRulesConnector.routes(serviceName) - inconsistentRoutes = routeRulesService.serviceRoutes(allRoutes) + routes <- routesRulesConnector.routes(serviceName) + prodApiRoutes <- releasesConnector.apiServices(Environment.Production).map: apiService => + apiService.collect: + case api if api.serviceName == serviceName => + Route( + path = api.context, + ruleConfigurationUrl = None, + routeType = RouteType.ApiContext, + environment = api.environment + ) + allProdRoutes = routes.filter(_.environment == Environment.Production) ++ prodApiRoutes + inconsistentRoutes = routeRulesService.inconsistentRoutes(routes) optLatestServiceInfo <- serviceDependenciesConnector.getSlugInfo(serviceName) serviceCostEstimate <- costEstimationService.estimateServiceCost(serviceName) commenterReport <- prCommenterConnector.report(repositoryName) @@ -241,7 +239,7 @@ class CatalogueController @Inject() ( envDatas = optLatestData.fold(envDatas)(envDatas + _), linkToLeakDetection = urlIfLeaksFound, prodRoutes = allProdRoutes, - serviceRoutes = inconsistentRoutes, + inconsistentRoutes = inconsistentRoutes, hasBranchProtectionAuth = hasBranchProtectionAuth, commenterReport = commenterReport, serviceRelationships = serviceRelationships, diff --git a/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala b/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala index 38f7f7841..e09a03724 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala @@ -18,7 +18,7 @@ package uk.gov.hmrc.cataloguefrontend.connector import play.api.Logger import play.api.libs.functional.syntax.* -import play.api.libs.json.{JsResult, Reads, __} +import play.api.libs.json.{Reads, __} import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName} import uk.gov.hmrc.http.{HeaderCarrier, HttpReads, StringContextOps} import uk.gov.hmrc.http.client.HttpClientV2 diff --git a/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala b/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala index 30375ce31..1642c5562 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala @@ -16,53 +16,29 @@ package uk.gov.hmrc.cataloguefrontend.service -import javax.inject.{Inject, Singleton} +import javax.inject.Singleton import uk.gov.hmrc.cataloguefrontend.model.Environment -import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} -import uk.gov.hmrc.http.HeaderCarrier - -import scala.concurrent.ExecutionContext @Singleton -class RouteRulesService @Inject()( -)(using ExecutionContext): - - import RouteRulesService._ - - // TODO replace with - // def inconsistentRoutes(routes: Seq[Route])(using HeaderCarrier): Seq[Route] = - - def serviceRoutes(routes: Seq[Route])(using HeaderCarrier): ServiceRoutes = - // exclude new Devhub route type for now - ServiceRoutes(routes.filterNot(_.routeType == RouteType.Devhub)) +class RouteRulesService: - -object RouteRulesService: - case class ServiceRoutes( - routes: Seq[Route] - ): - - private val referenceRoutes: Seq[Route] = + def inconsistentRoutes(routes: Seq[Route]): Seq[Route] = + val referenceRoutes: Seq[Route] = for referenceEnv <- routes.map(_.environment).sorted.reverse.headOption.toSeq routes <- routes.filter(_.environment == referenceEnv) yield routes - val inconsistentRoutes = - routes.groupBy(_.environment) - .collect: - case (_, envRoutes) => - val differentPaths = - envRoutes - .map(_.path) - .diff(referenceRoutes.map(_.path)) - envRoutes.filter: r => - differentPaths.contains(r.path) - .flatten - .toSeq - - val hasInconsistentRoutes: Boolean = - inconsistentRoutes.nonEmpty - + routes + .filterNot(_.routeType == RouteType.Devhub) // exclude new Devhub route type for now + .groupBy(_.environment) + .collect: + case (_, envRoutes) => + val differentPaths = envRoutes.map(_.path).diff(referenceRoutes.map(_.path)) + envRoutes.filter: r => + differentPaths.contains(r.path) + .flatten + .toSeq + end RouteRulesService diff --git a/app/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterService.scala b/app/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterService.scala index ea34af643..522bc0731 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterService.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterService.scala @@ -21,13 +21,13 @@ import cats.implicits.* import javax.inject.{Inject, Singleton} import uk.gov.hmrc.cataloguefrontend.connector.{GitHubProxyConnector, RouteRulesConnector} +import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.RouteType import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName} import uk.gov.hmrc.internalauth.client.AuthenticatedRequest import uk.gov.hmrc.http.HeaderCarrier import scala.concurrent.{ExecutionContext, Future} import org.jsoup.nodes.Document -import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.RouteType @Singleton class ShutterService @Inject() ( diff --git a/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html b/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html index 096f4bfb5..cf112de06 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html +++ b/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html @@ -18,9 +18,7 @@ @import uk.gov.hmrc.cataloguefrontend.connector.{GitRepository, JenkinsJob} @import uk.gov.hmrc.cataloguefrontend.prcommenter.PrCommenterReport @import uk.gov.hmrc.cataloguefrontend.cost.{CostEstimateConfig, ServiceCostEstimate} -@import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService.ServiceRoutes -@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.Route -@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.RouteType +@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} @import uk.gov.hmrc.cataloguefrontend.servicecommissioningstatus.Lifecycle @import uk.gov.hmrc.cataloguefrontend.serviceconfigs.ServiceConfigsService @import uk.gov.hmrc.cataloguefrontend.view.ViewMessages @@ -40,7 +38,7 @@ envDatas : Map[SlugInfoFlag, EnvData], linkToLeakDetection : Option[String], prodRoutes : Seq[Route], - serviceRoutes : ServiceRoutes, + inconsistentRoutes : Seq[Route], hasBranchProtectionAuth : EnableBranchProtection.HasAuthorisation, commenterReport : Option[PrCommenterReport], serviceRelationships : ServiceConfigsService.ServiceRelationshipsEnriched, @@ -104,10 +102,10 @@

} - @if(serviceRoutes.hasInconsistentRoutes) { + @if(inconsistentRoutes.nonEmpty) {
- @partials.serviceRouteRuleViolations(serviceRoutes) + @partials.serviceRouteRuleViolations(inconsistentRoutes)
} diff --git a/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceRouteRuleViolations.scala.html b/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceRouteRuleViolations.scala.html index 0f2475bc8..c0842458b 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceRouteRuleViolations.scala.html +++ b/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceRouteRuleViolations.scala.html @@ -14,11 +14,11 @@ * limitations under the License. *@ -@import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService.ServiceRoutes +@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.Route -@(serviceRoutes: ServiceRoutes) +@(inconsistentRoutes: Seq[Route]) -@if(serviceRoutes.hasInconsistentRoutes) { +@if(inconsistentRoutes.nonEmpty) {
Inconsistent Route Rules
@@ -30,7 +30,7 @@ Route Rule - @for(route <- serviceRoutes.inconsistentRoutes) { + @for(route <- inconsistentRoutes) { @route.environment diff --git a/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceUrlDetails.scala.html b/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceUrlDetails.scala.html index cec9acda8..b2cdee59b 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceUrlDetails.scala.html +++ b/app/uk/gov/hmrc/cataloguefrontend/view/partials/serviceUrlDetails.scala.html @@ -14,8 +14,7 @@ * limitations under the License. *@ -@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.Route -@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.RouteType +@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} @(routes: Seq[Route])
diff --git a/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala b/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala index 9b39eaac5..11a51fc67 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala @@ -20,24 +20,25 @@ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} import uk.gov.hmrc.cataloguefrontend.model.Environment -import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService.ServiceRoutes class RouteRulesServiceSpec extends AnyWordSpec with Matchers: + private val routeRulesService = RouteRulesService() + "Service" should { "return no result for inconsistency check when no environment routes" in { - val inconsistentRoutes = ServiceRoutes(Nil).inconsistentRoutes + val inconsistentRoutes = Seq.empty[Route] inconsistentRoutes.nonEmpty shouldBe false } "determine if there is inconsistency in the public URL rules" in { - val envRoutes = Seq( + val routes = Seq( Route("frontendPath", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.Production), Route("frontendPath", Some("ruleConfigurationUrlQa"), false, RouteType.Frontend, Environment.QA ), Route("inconsistent", Some("ruleConfigurationUrlQa"), false, RouteType.Frontend, Environment.QA ) ) - val inconsistentRoutes = ServiceRoutes(envRoutes).inconsistentRoutes + val inconsistentRoutes = routeRulesService.inconsistentRoutes(routes) inconsistentRoutes.nonEmpty shouldBe true inconsistentRoutes.head.environment shouldBe Environment.QA inconsistentRoutes.length shouldBe 1 @@ -45,29 +46,30 @@ class RouteRulesServiceSpec extends AnyWordSpec with Matchers: } "determine if there is inconsistency with public URL rules when duplicates exist" in { - val environmentRoutes = Seq( + val routes = Seq( Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.Production), Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.Production), - Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.QA), - Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.QA), - Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.QA) + Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.QA ), + Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.QA ), + Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.QA ) ) - val inconsistentRoutes = ServiceRoutes(environmentRoutes).inconsistentRoutes + val inconsistentRoutes = routeRulesService.inconsistentRoutes(routes) inconsistentRoutes.nonEmpty shouldBe true inconsistentRoutes.head.environment shouldBe Environment.QA } "determine if there is consistency with public URL rules" in { - val environmentRoutes = Seq( + val routes = Seq( Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.Production), Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.Production), - Route("frontendPathOne", Some("ruleConfigurationUrlOne"), false, RouteType.Frontend, Environment.QA ), Route("frontendPathTwo", Some("ruleConfigurationUrlTwo"), false, RouteType.Frontend, Environment.QA ) ) - ServiceRoutes(environmentRoutes).inconsistentRoutes.nonEmpty shouldBe false + val inconsistentRoutes = routeRulesService.inconsistentRoutes(routes) + + inconsistentRoutes.nonEmpty shouldBe false } "determine if there is inconsistency in the URL paths" in { @@ -77,16 +79,18 @@ class RouteRulesServiceSpec extends AnyWordSpec with Matchers: Route("inconsistent", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA ) ) - val inconsistentRoutes = ServiceRoutes(routes).inconsistentRoutes + val inconsistentRoutes = routeRulesService.inconsistentRoutes(routes) inconsistentRoutes shouldBe Seq( Route("inconsistent", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA) ) } "be consistent when no routes" in { - val environmentRoutes = Seq.empty[Route] + val routes = Seq.empty[Route] + + val inconsistentRoutes = routeRulesService.inconsistentRoutes(routes) - ServiceRoutes(environmentRoutes).inconsistentRoutes.nonEmpty shouldBe false + inconsistentRoutes.nonEmpty shouldBe false } "handle Admin and Frontend routes" in { @@ -103,8 +107,8 @@ class RouteRulesServiceSpec extends AnyWordSpec with Matchers: Route("/fhdds", Some(""), false, RouteType.Frontend, Environment.Integration), Route("/fhdds", Some(""), false, RouteType.Frontend, Environment.Development) ) - - val inconsistentRoutes = ServiceRoutes(adminRoutes ++ frontendRoutes).inconsistentRoutes + + val inconsistentRoutes = routeRulesService.inconsistentRoutes(adminRoutes ++ frontendRoutes) // we only show additional routes in lower envs, not missing routes (currently..) inconsistentRoutes.nonEmpty shouldBe false } diff --git a/test/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterServiceSpec.scala b/test/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterServiceSpec.scala index 1e739b290..b8140f641 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterServiceSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterServiceSpec.scala @@ -22,7 +22,6 @@ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import org.scalatestplus.mockito.MockitoSugar import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} -import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.RouteType.Frontend import uk.gov.hmrc.cataloguefrontend.connector.{GitHubProxyConnector, RouteRulesConnector} import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName, UserName} import uk.gov.hmrc.http.HeaderCarrier diff --git a/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala b/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala index 4a47333dc..44ee03c04 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala @@ -20,29 +20,33 @@ import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} import uk.gov.hmrc.cataloguefrontend.model.Environment -import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService.ServiceRoutes +import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService class ServiceRouteRuleViolationsSpec extends AnyWordSpec with Matchers { + + private val routeRuleService = RouteRulesService() - val misMatchedServiceRoutes = ServiceRoutes(Seq( + val misMatchedRoutes = Seq( Route("TestUrl0", Some("ruleConfigurationUrl0"), false, RouteType.Frontend, Environment.Development), Route("TestUrl1", Some("ruleConfigurationUrl1"), false, RouteType.Frontend, Environment.Production ) - )) + ) - val matchingServiceRoutes = ServiceRoutes(Seq( + val matchingRoutes = Seq( Route("TestUrl0", Some("ruleConfigurationUrl0"), false, RouteType.Frontend, Environment.Development), - Route("TestUrl0", Some("ruleConfigurationUrl1"), false, RouteType.Frontend, Environment.Production) - )) + Route("TestUrl0", Some("ruleConfigurationUrl1"), false, RouteType.Frontend, Environment.Production ) + ) "ServiceRouteRuleViolations" should { "display when there are URLs not matching" in { - val result = serviceRouteRuleViolations(misMatchedServiceRoutes).body + val inconsistentRoutes = routeRuleService.inconsistentRoutes(misMatchedRoutes) + val result = serviceRouteRuleViolations(inconsistentRoutes).body result should include ("id=\"routing-rule-violations\"") } - "do not display when there are URLs are matching" in { - val result = serviceRouteRuleViolations(matchingServiceRoutes).body + "do not display when there are URLs matching" in { + val inconsistentRoutes = routeRuleService.inconsistentRoutes(matchingRoutes) + val result = serviceRouteRuleViolations(inconsistentRoutes).body result should not include ("id=\"routing-rule-violations\"") } }