diff --git a/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala b/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala index 3d59b5fbd..29e764f9b 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala @@ -27,6 +27,7 @@ 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 @@ -37,8 +38,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.whatsrunningwhere.{ReleasesConnector, WhatsRunningWhereService} import uk.gov.hmrc.cataloguefrontend.vulnerabilities.VulnerabilitiesConnector -import uk.gov.hmrc.cataloguefrontend.whatsrunningwhere.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 +64,8 @@ class CatalogueController @Inject() ( teamsAndRepositoriesConnector : TeamsAndRepositoriesConnector, serviceConfigsService : ServiceConfigsService, costEstimationService : CostEstimationService, - costEstimateConfig : CostEstimateConfig, routeRulesService : RouteRulesService, + costEstimateConfig : CostEstimateConfig, serviceDependenciesConnector : ServiceDependenciesConnector, serviceCommissioningStatusConnector: ServiceCommissioningStatusConnector, leakDetectionService : LeakDetectionService, @@ -84,6 +85,8 @@ class CatalogueController @Inject() ( repositoryInfoPage : RepositoryInfoPage, serviceMetricsConnector : ServiceMetricsConnector, serviceConfigsConnector : ServiceConfigsConnector, + releasesConnector : ReleasesConnector, + routesRulesConnector : RouteRulesConnector, override val auth : FrontendAuthComponents )(using override val ec: ExecutionContext @@ -193,7 +196,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) + 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) @@ -224,7 +238,8 @@ class CatalogueController @Inject() ( repositoryCreationDate = repositoryDetails.createdDate, envDatas = optLatestData.fold(envDatas)(envDatas + _), linkToLeakDetection = urlIfLeaksFound, - serviceRoutes = serviceRoutes, + prodRoutes = allProdRoutes, + 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 83b1be6b4..e09a03724 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/connector/RouteRulesConnector.scala @@ -17,7 +17,7 @@ package uk.gov.hmrc.cataloguefrontend.connector import play.api.Logger -import play.api.libs.functional.syntax._ +import play.api.libs.functional.syntax.* import play.api.libs.json.{Reads, __} import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName} import uk.gov.hmrc.http.{HeaderCarrier, HttpReads, StringContextOps} @@ -40,92 +40,62 @@ 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}?routeType=${routeType.map(_.asString)}&environment=${environment.map(_.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 - ) + import uk.gov.hmrc.cataloguefrontend.util.{FromString, FromStringEnum, Parser} + import FromStringEnum._ - case class EnvironmentRoute( - environment: Environment - , routes : Seq[Route] - , isAdmin : Boolean = false - ) - - 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..1642c5562 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/service/RouteRulesService.scala @@ -16,75 +16,29 @@ package uk.gov.hmrc.cataloguefrontend.service -import javax.inject.{Inject, Singleton} -import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName} -import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector -import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.EnvironmentRoute -import uk.gov.hmrc.http.HeaderCarrier - -import scala.concurrent.{ExecutionContext, Future} - -class RouteRulesService @Inject() ( - routeRulesConnector: RouteRulesConnector -)(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) +import javax.inject.Singleton +import uk.gov.hmrc.cataloguefrontend.model.Environment +import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, RouteType} @Singleton -object RouteRulesService: - case class ServiceRoutes( - environmentRoutes: Seq[EnvironmentRoute] - ): - 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 def hasDifferentRoutesToReferenceEnvironment(environmentRoute: EnvironmentRoute, referenceEnvironmentRoute: EnvironmentRoute) = - environmentRoute.routes - .map(_.frontendPath) - .diff(referenceEnvironmentRoute.routes.map(_.frontendPath)) - .nonEmpty - - private def filterRoutesToDifferences(environmentRoute: EnvironmentRoute, referenceEnvironmentRoute: EnvironmentRoute) = - environmentRoute.routes - .filter: r => - environmentRoute.routes - .map(_.frontendPath) - .diff(referenceEnvironmentRoute.routes.map(_.frontendPath)) - .contains(r.frontendPath) - - 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 hasInconsistentRoutes: Boolean = - inconsistentRoutes.nonEmpty - - val isDefined: Boolean = - environmentRoutes.nonEmpty - - end ServiceRoutes - +class RouteRulesService: + + 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 + + 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/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..522bc0731 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterService.scala +++ b/app/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterService.scala @@ -17,9 +17,11 @@ 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.connector.RouteRulesConnector.RouteType import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName} import uk.gov.hmrc.internalauth.client.AuthenticatedRequest import uk.gov.hmrc.http.HeaderCarrier @@ -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..cf112de06 100644 --- a/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html +++ b/app/uk/gov/hmrc/cataloguefrontend/view/ServiceInfoPage.scala.html @@ -18,7 +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, RouteType} @import uk.gov.hmrc.cataloguefrontend.servicecommissioningstatus.Lifecycle @import uk.gov.hmrc.cataloguefrontend.serviceconfigs.ServiceConfigsService @import uk.gov.hmrc.cataloguefrontend.view.ViewMessages @@ -37,7 +37,8 @@ repositoryCreationDate : Instant, envDatas : Map[SlugInfoFlag, EnvData], linkToLeakDetection : Option[String], - serviceRoutes : ServiceRoutes, + prodRoutes : Seq[Route], + inconsistentRoutes : Seq[Route], hasBranchProtectionAuth : EnableBranchProtection.HasAuthorisation, commenterReport : Option[PrCommenterReport], serviceRelationships : ServiceConfigsService.ServiceRelationshipsEnriched, @@ -93,26 +94,18 @@

- @serviceRoutes.environmentRoutes.find(er => er.environment == Environment.Production && !er.isAdmin).map { envRoute => + @if(prodRoutes.nonEmpty) {
- @partials.serviceUrlDetails(envRoute, isAdmin = false) + @partials.serviceUrlDetails(prodRoutes)
} - @serviceRoutes.environmentRoutes.find(er => er.environment == Environment.Production && er.isAdmin).map { envRoute => + @if(inconsistentRoutes.nonEmpty) {
- @partials.serviceUrlDetails(envRoute, isAdmin = true) -
-
- } - - @if(serviceRoutes.hasInconsistentRoutes) { -
-
- @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 0d3f34b49..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,17 +30,15 @@ Route Rule - @for(environmentRoute <- serviceRoutes.inconsistentRoutes) { - @for(route <- environmentRoute.routes) { + @for(route <- 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..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,34 +14,41 @@ * limitations under the License. *@ -@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.EnvironmentRoute +@import uk.gov.hmrc.cataloguefrontend.connector.RouteRulesConnector.{Route, 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(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 32b33749f..6f88c544d 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/ServicePageSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/ServicePageSpec.scala @@ -35,19 +35,20 @@ class ServicePageSpec extends UnitSpec with FakeApplicationBuilder { super.beforeEach() 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/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("[]"))) - serviceEndpoint(GET, "/service-configs/service-relationships/service-1" , willRespondWith = (200, Some(JsonData.serviceRelationships))) - serviceEndpoint(GET, "/service-configs/service-relationships/service-name" , willRespondWith = (200, Some(JsonData.serviceRelationships))) - serviceEndpoint(GET, "/api/v2/repositories" , willRespondWith = (200, Some("[]"))) - serviceEndpoint(GET, "/service-configs/deployment-config?serviceName=repo1" , willRespondWith = (200, Some(JsonData.deploymentConfigsService1))) - serviceEndpoint(GET, "/service-configs/deployment-config?serviceName=service-1" , willRespondWith = (200, Some(JsonData.deploymentConfigsService1))) - serviceEndpoint(GET, "/service-metrics/service-1/non-performant-queries" , willRespondWith = (200, Some("""[{"service": "service-1", "environment": "qa", "queryTypes": ["Slow Running"]}]"""))) - serviceEndpoint(GET, "/service-metrics/service-1/collections" , willRespondWith = (200, Some("""[{"database": "database-1", "service": "service-1", "sizeBytes": 1024, "date": "2023-11-06", "collection": "collection-1", "environment": "qa", "queryTypes": []}]"""))) - serviceEndpoint(GET, "/service-commissioning-status/services/service-1/lifecycleStatus" , willRespondWith = (200, Some("""{ "lifecycleStatus" : "Active" }"""))) + serviceEndpoint(GET, "/reports/repositories", willRespondWith = (200, Some("[]"))) + 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("[]"))) + serviceEndpoint(GET, "/service-configs/service-relationships/service-1", willRespondWith = (200, Some(JsonData.serviceRelationships))) + serviceEndpoint(GET, "/service-configs/service-relationships/service-name", willRespondWith = (200, Some(JsonData.serviceRelationships))) + serviceEndpoint(GET, "/api/v2/repositories", willRespondWith = (200, Some("[]"))) + serviceEndpoint(GET, "/service-configs/deployment-config?serviceName=repo1", willRespondWith = (200, Some(JsonData.deploymentConfigsService1))) + serviceEndpoint(GET, "/service-configs/deployment-config?serviceName=service-1", willRespondWith = (200, Some(JsonData.deploymentConfigsService1))) + serviceEndpoint(GET, "/service-metrics/service-1/non-performant-queries", willRespondWith = (200, Some("""[{"service": "service-1", "environment": "qa", "queryTypes": ["Slow Running"]}]"""))) + serviceEndpoint(GET, "/service-metrics/service-1/collections", willRespondWith = (200, Some("""[{"database": "database-1", "service": "service-1", "sizeBytes": 1024, "date": "2023-11-06", "collection": "collection-1", "environment": "qa", "queryTypes": []}]"""))) + serviceEndpoint(GET, "/service-commissioning-status/services/service-1/lifecycleStatus", willRespondWith = (200, Some("""{ "lifecycleStatus" : "Active" }"""))) serviceEndpoint(GET, s"/vulnerabilities/api/reports/latest/counts?service=%22service-1%22", willRespondWith = (200, Some("[]"))) serviceEndpoint(GET, s"/vulnerabilities/api/reports/qa/counts?service=%22service-1%22" , willRespondWith = (200, Some("[]"))) serviceEndpoint(GET, s"/vulnerabilities/api/reports/production/counts?service=%22service-1%22", 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..11a51fc67 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/service/RouteRulesServiceSpec.scala @@ -18,179 +18,98 @@ 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.{Route, RouteType} import uk.gov.hmrc.cataloguefrontend.model.Environment -import uk.gov.hmrc.cataloguefrontend.service.RouteRulesService.ServiceRoutes -class RouteRulesServiceSpec extends AnyWordSpec with Matchers { +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 environmentRoutes = Seq( - EnvironmentRoute(Environment.Production, Seq(Route("frontendPath", "ruleConfigurationUrl"))), - EnvironmentRoute(Environment.QA, - Seq( - Route("frontendPath", "ruleConfigurationUrlQa"), - Route("inconsistent", "ruleConfigurationUrlQa") - ) - ) + 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(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 = routeRulesService.inconsistentRoutes(routes) + 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") - )) + 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 ) ) - 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( - EnvironmentRoute(Environment.Production, Seq( - Route("frontendPathOne", "ruleConfigurationUrlOne"), - Route("frontendPathTwo", "ruleConfigurationUrlTwo") - )), - EnvironmentRoute(Environment.QA, Seq( - Route("frontendPathOne", "ruleConfigurationUrlOne"), - Route("frontendPathTwo", "ruleConfigurationUrlTwo") - )) + 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 - } - - "be consistent when no routes" in { - val environmentRoutes = Seq( - EnvironmentRoute(Environment.Production, Seq.empty), - EnvironmentRoute(Environment.QA , Seq.empty) - ) + val inconsistentRoutes = routeRulesService.inconsistentRoutes(routes) - ServiceRoutes(environmentRoutes).inconsistentRoutes.nonEmpty shouldBe false + 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"))) + "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 ) ) - ServiceRoutes(environmentRoutes).referenceEnvironmentRoutes.isDefined shouldBe true - } - - "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"))) + val inconsistentRoutes = routeRulesService.inconsistentRoutes(routes) + inconsistentRoutes shouldBe Seq( + Route("inconsistent", Some("ruleConfigurationUrl"), false, RouteType.Frontend, Environment.QA) ) - - ServiceRoutes(environmentRoutes).referenceEnvironmentRoutes.isDefined shouldBe true } - "return no reference environment when no environment routes" in { - val environmentRoutes: Seq[EnvironmentRoute] = Nil + "be consistent when no routes" in { + val routes = Seq.empty[Route] + + val inconsistentRoutes = routeRulesService.inconsistentRoutes(routes) - ServiceRoutes(environmentRoutes).referenceEnvironmentRoutes.isDefined shouldBe false + inconsistentRoutes.nonEmpty shouldBe false } "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 + + 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 9c371eb14..b8140f641 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterServiceSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/shuttering/ShutterServiceSpec.scala @@ -21,6 +21,7 @@ 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.{GitHubProxyConnector, RouteRulesConnector} import uk.gov.hmrc.cataloguefrontend.model.{Environment, ServiceName, UserName} import uk.gov.hmrc.http.HeaderCarrier @@ -110,6 +111,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 +140,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..44ee03c04 100644 --- a/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala +++ b/test/uk/gov/hmrc/cataloguefrontend/view/partials/html/ServiceRouteRuleViolationsSpec.scala @@ -18,42 +18,35 @@ 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.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( - EnvironmentRoute( - environment = Environment.Development, - routes = Seq(Route("TestUrl0", "ruleConfigurationUrl0")) - ), - EnvironmentRoute( - environment = Environment.Production, - routes = Seq(Route("TestUrl1", "ruleConfigurationUrl1")) - ) - )) + 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( - EnvironmentRoute( - environment = Environment.Development, - routes = Seq(Route("TestUrl0", "ruleConfigurationUrl0")) - ), - EnvironmentRoute( - environment = Environment.Production, - routes = Seq(Route("TestUrl0", "ruleConfigurationUrl1")) - ) - )) + val matchingRoutes = 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 + 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\"") } }