From 59657e199d707860ceb3eaf9ed82776c66062cd6 Mon Sep 17 00:00:00 2001 From: peteslater-ee <28756214+peteslater-ee@users.noreply.github.com> Date: Fri, 7 Aug 2026 13:10:02 +0100 Subject: [PATCH 1/5] API-9170 - Removing restriction on fetching OAS resources for CONTROLLED APIs --- .../hmrc/apidocumentation/controllers/DownloadController.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/uk/gov/hmrc/apidocumentation/controllers/DownloadController.scala b/app/uk/gov/hmrc/apidocumentation/controllers/DownloadController.scala index 80f302db..ea9d5e2d 100644 --- a/app/uk/gov/hmrc/apidocumentation/controllers/DownloadController.scala +++ b/app/uk/gov/hmrc/apidocumentation/controllers/DownloadController.scala @@ -78,7 +78,7 @@ class DownloadController @Inject() ( )) findVersion(apiOption) match { - case Some((api, _, VersionVisibility(ApiAccessType.CONTROLLED | ApiAccessType.INTERNAL, false, _))) => + case Some((api, _, VersionVisibility(ApiAccessType.INTERNAL, false, _))) => redirectToLoginPage(api.serviceName) case Some((api, selectedVersion, VersionVisibility(_, _, true))) => From 1797f123dab187658cff08ba13e049f204b70b1e Mon Sep 17 00:00:00 2001 From: peteslater-ee <28756214+peteslater-ee@users.noreply.github.com> Date: Mon, 10 Aug 2026 14:58:05 +0100 Subject: [PATCH 2/5] API-9170 - Adding new links for API endpoints --- .../views/helpers/Helpers.scala | 16 ++++---- .../openapispec/ParentPageView.scala.html | 25 +++++++++--- .../ApiDocumentationControllerSpec.scala | 38 ++++++++++--------- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/app/uk/gov/hmrc/apidocumentation/views/helpers/Helpers.scala b/app/uk/gov/hmrc/apidocumentation/views/helpers/Helpers.scala index 0cd1c35f..e133710f 100644 --- a/app/uk/gov/hmrc/apidocumentation/views/helpers/Helpers.scala +++ b/app/uk/gov/hmrc/apidocumentation/views/helpers/Helpers.scala @@ -97,17 +97,17 @@ object ShowBaseURL { object VersionDocsVisible { def apply(availability: Option[VersionVisibility]): DocsVisibility = availability match { - case Some(VersionVisibility(ApiAccessType.PUBLIC, _, _)) => DocsVisibility.VISIBLE // PUBLIC - case Some(VersionVisibility(_, true, true)) => DocsVisibility.VISIBLE // Not Public, logged in, authorised (subscribed) - case Some(VersionVisibility(ApiAccessType.CONTROLLED, _, false)) => DocsVisibility.OVERVIEW_ONLY // CONTROLLED but not authorised (not subscribed) - case _ => DocsVisibility.NOT_VISIBLE + case Some(VersionVisibility(ApiAccessType.PUBLIC | ApiAccessType.CONTROLLED, _, _)) => DocsVisibility.VISIBLE // PUBLIC or CONTROLLED(signed in or out), both can see API documentation + // case Some(VersionVisibility(ApiAccessType.CONTROLLED, _, _)) => DocsVisibility.VISIBLE // CONTROLLED but not authorised (not subscribed) + case Some(VersionVisibility(_, true, true)) => DocsVisibility.VISIBLE // Not Public, logged in, authorised (subscribed) + case _ => DocsVisibility.NOT_VISIBLE } def apply(version: ExtendedApiVersion): DocsVisibility = VersionVisibility(version) match { - case Some(VersionVisibility(ApiAccessType.PUBLIC, _, _)) => DocsVisibility.VISIBLE // PUBLIC - case Some(VersionVisibility(_, true, true)) => DocsVisibility.VISIBLE // Not Public, logged in, authorised (subscribed) - case Some(VersionVisibility(ApiAccessType.CONTROLLED, _, false)) => DocsVisibility.OVERVIEW_ONLY // CONTROLLED but not authorised (not subscribed) - case _ => DocsVisibility.NOT_VISIBLE + case Some(VersionVisibility(ApiAccessType.PUBLIC | ApiAccessType.CONTROLLED, _, _)) => DocsVisibility.VISIBLE // PUBLIC or CONTROLLED(signed in or out), both can see API documentation + // case Some(VersionVisibility(ApiAccessType.CONTROLLED, _, _)) => DocsVisibility.VISIBLE // CONTROLLED but not authorised (not subscribed) + case Some(VersionVisibility(_, true, true)) => DocsVisibility.VISIBLE // Not Public, logged in, authorised (subscribed) + case _ => DocsVisibility.NOT_VISIBLE } } diff --git a/app/uk/gov/hmrc/apidocumentation/views/openapispec/ParentPageView.scala.html b/app/uk/gov/hmrc/apidocumentation/views/openapispec/ParentPageView.scala.html index 4db68ca0..60183d75 100644 --- a/app/uk/gov/hmrc/apidocumentation/views/openapispec/ParentPageView.scala.html +++ b/app/uk/gov/hmrc/apidocumentation/views/openapispec/ParentPageView.scala.html @@ -29,6 +29,13 @@ @(markdownBlocks: List[DocumentationItem], title: String, maybeVersion: Option[ExtendedApiVersion], maybeApi: Option[ExtendedApiDefinition], loggedIn: Boolean = false )(implicit requestHeader: RequestHeader) +@requestAccess(version: ExtendedApiVersion) = { + @{version.sandboxAvailability.orElse(version.productionAvailability).map(x => x.access) match { + case Some(ApiAccessType.CONTROLLED) => Request access + case _ => "" + }} +} +
@@ -118,13 +125,21 @@

@ShowAvailabilityInEnvironment(EndpointsAvailable(version.sandboxAvailability), EndpointsAvailable(version.productionAvailability), applicationConfig) - @if(visibility == DocsVisibility.VISIBLE) { - - @version.version.toString() - endpoints + + + + + + + +
+ View endpoints +
+ @requestAccess(version) +
} else { @if(visibility == DocsVisibility.OVERVIEW_ONLY & loggedIn) { - Request access + Request access } else { Sign in to request access }} diff --git a/test/uk/gov/hmrc/apidocumentation/controllers/ApiDocumentationControllerSpec.scala b/test/uk/gov/hmrc/apidocumentation/controllers/ApiDocumentationControllerSpec.scala index f95016d7..98ee0e76 100644 --- a/test/uk/gov/hmrc/apidocumentation/controllers/ApiDocumentationControllerSpec.scala +++ b/test/uk/gov/hmrc/apidocumentation/controllers/ApiDocumentationControllerSpec.scala @@ -213,24 +213,26 @@ class ApiDocumentationControllerSpec extends CommonControllerBaseSpec with PageR verifyPageRendered(pageTitle("Hello World"), bodyContains = Seq("> stable"))(result) } - "display the API landing page with 'Request access' button for private trial when logged in" in new Setup { - theUserIsLoggedIn() - theDefinitionServiceWillReturnAnApiDefinition( - extendedApiDefinitionWithPrincipalAndSubordinateAPIAvailability( - serviceName, - versionOne, - Some(ApiAvailability(true, ApiAccessType.CONTROLLED, true, false)), - Some(ApiAvailability(true, ApiAccessType.CONTROLLED, true, false)) - ) - ) - DownloadConnectorMock.Fetch.returnsNoneIfNotFound() - - val result = underTest.renderApiDocumentation(serviceName, versionOne)(request) - - verifyApiDocumentationPageRendered(result) - verifyPageRendered(pageTitle("Hello World"), bodyContains = Seq("> stable", "Request access"))(result) - } - + // NB: This test doesn't make sense in the context of CONTROLLED APIs having public OAS docs - Candidate for removal + // "display the API landing page with 'Request access' button for private trial when logged in" in new Setup { + // theUserIsLoggedIn() + // theDefinitionServiceWillReturnAnApiDefinition( + // extendedApiDefinitionWithPrincipalAndSubordinateAPIAvailability( + // serviceName, + // versionOne, + // Some(ApiAvailability(true, ApiAccessType.CONTROLLED, true, false)), + // Some(ApiAvailability(true, ApiAccessType.CONTROLLED, true, false)) + // ) + // ) + // DownloadConnectorMock.Fetch.returnsNoneIfNotFound() + + // val result = underTest.renderApiDocumentation(serviceName, versionOne)(request) + + // verifyApiDocumentationPageRendered(result) + // verifyPageRendered(pageTitle("Hello World"), bodyContains = Seq("> stable", "Request access"))(result) + // } + + // TODO: This test is badly named now that CONTROLLED APIs have publically viewable OAS docs = Rename? "display the API landing page with NO 'Request access' button for private trial when not logged in" in new Setup { theUserIsNotLoggedIn() theDefinitionServiceWillReturnAnApiDefinition( From 828463802299d3f53b24495ed2b772bd89de83d9 Mon Sep 17 00:00:00 2001 From: peteslater-ee <28756214+peteslater-ee@users.noreply.github.com> Date: Tue, 11 Aug 2026 11:03:24 +0100 Subject: [PATCH 3/5] API-9170 - Comment out test that may no longer be needed --- .../ApiDocumentationControllerSpec.scala | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/test/uk/gov/hmrc/apidocumentation/controllers/ApiDocumentationControllerSpec.scala b/test/uk/gov/hmrc/apidocumentation/controllers/ApiDocumentationControllerSpec.scala index 98ee0e76..e3bd0e6f 100644 --- a/test/uk/gov/hmrc/apidocumentation/controllers/ApiDocumentationControllerSpec.scala +++ b/test/uk/gov/hmrc/apidocumentation/controllers/ApiDocumentationControllerSpec.scala @@ -213,7 +213,7 @@ class ApiDocumentationControllerSpec extends CommonControllerBaseSpec with PageR verifyPageRendered(pageTitle("Hello World"), bodyContains = Seq("> stable"))(result) } - // NB: This test doesn't make sense in the context of CONTROLLED APIs having public OAS docs - Candidate for removal + // NB: These tests don't make sense in the context of CONTROLLED APIs having public OAS docs - Candidates for removal // "display the API landing page with 'Request access' button for private trial when logged in" in new Setup { // theUserIsLoggedIn() // theDefinitionServiceWillReturnAnApiDefinition( @@ -232,25 +232,24 @@ class ApiDocumentationControllerSpec extends CommonControllerBaseSpec with PageR // verifyPageRendered(pageTitle("Hello World"), bodyContains = Seq("> stable", "Request access"))(result) // } - // TODO: This test is badly named now that CONTROLLED APIs have publically viewable OAS docs = Rename? - "display the API landing page with NO 'Request access' button for private trial when not logged in" in new Setup { - theUserIsNotLoggedIn() - theDefinitionServiceWillReturnAnApiDefinition( - extendedApiDefinitionWithPrincipalAndSubordinateAPIAvailability( - serviceName, - versionOne, - Some(ApiAvailability(true, ApiAccessType.CONTROLLED, false, false)), - Some(ApiAvailability(true, ApiAccessType.CONTROLLED, false, false)) - ) - ) - DownloadConnectorMock.Fetch.returnsNoneIfNotFound() + // "display the API landing page with NO 'Request access' button for private trial when not logged in" in new Setup { + // theUserIsNotLoggedIn() + // theDefinitionServiceWillReturnAnApiDefinition( + // extendedApiDefinitionWithPrincipalAndSubordinateAPIAvailability( + // serviceName, + // versionOne, + // Some(ApiAvailability(true, ApiAccessType.CONTROLLED, false, false)), + // Some(ApiAvailability(true, ApiAccessType.CONTROLLED, false, false)) + // ) + // ) + // DownloadConnectorMock.Fetch.returnsNoneIfNotFound() - val result = underTest.renderApiDocumentation(serviceName, versionOne)(request) + // val result = underTest.renderApiDocumentation(serviceName, versionOne)(request) - verifyApiDocumentationPageRendered(result) - verifyPageRendered(pageTitle("Hello World"), bodyContains = Seq("> stable"))(result) - verifyPageDoesNotContain(texts = Seq("Request access"))(result) - } + // verifyApiDocumentationPageRendered(result) + // verifyPageRendered(pageTitle("Hello World"), bodyContains = Seq("> stable"))(result) + // verifyPageDoesNotContain(texts = Seq("Request access"))(result) + // } "display the not found page when invalid version specified" in new Setup { theUserIsLoggedIn() From 688a56b69d65b618b50550461c5ee54d46f7d96a Mon Sep 17 00:00:00 2001 From: peteslater-ee <28756214+peteslater-ee@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:19:38 +0100 Subject: [PATCH 4/5] API-9170 - Removing restriction on being authoirised when fetching resources to OAS rendering --- .../apidocumentation/controllers/DownloadController.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/uk/gov/hmrc/apidocumentation/controllers/DownloadController.scala b/app/uk/gov/hmrc/apidocumentation/controllers/DownloadController.scala index ea9d5e2d..411017da 100644 --- a/app/uk/gov/hmrc/apidocumentation/controllers/DownloadController.scala +++ b/app/uk/gov/hmrc/apidocumentation/controllers/DownloadController.scala @@ -81,7 +81,9 @@ class DownloadController @Inject() ( case Some((api, _, VersionVisibility(ApiAccessType.INTERNAL, false, _))) => redirectToLoginPage(api.serviceName) - case Some((api, selectedVersion, VersionVisibility(_, _, true))) => + // NB - Turning off the check for being logged in when downloading a resource to avoid the need to be logging in when fetching publicly viewable OAS + // case Some((api, selectedVersion, VersionVisibility(_, _, true))) => + case Some((api, selectedVersion, VersionVisibility(_, _, _))) => downloadConnector.fetch(api.serviceName, selectedVersion.version, validResource) .map(_.fold(renderNotFoundPage)(Future.successful)) .flatten From a8d8d7826503ef3d4788754a968a930639d03a40 Mon Sep 17 00:00:00 2001 From: peteslater-ee <28756214+peteslater-ee@users.noreply.github.com> Date: Tue, 11 Aug 2026 15:18:47 +0100 Subject: [PATCH 5/5] API-9170 - Removing comments and adding test for UI changes --- .../controllers/DownloadController.scala | 4 +- .../ApiDocumentationControllerSpec.scala | 54 ++++++------------- 2 files changed, 18 insertions(+), 40 deletions(-) diff --git a/app/uk/gov/hmrc/apidocumentation/controllers/DownloadController.scala b/app/uk/gov/hmrc/apidocumentation/controllers/DownloadController.scala index 411017da..4a365023 100644 --- a/app/uk/gov/hmrc/apidocumentation/controllers/DownloadController.scala +++ b/app/uk/gov/hmrc/apidocumentation/controllers/DownloadController.scala @@ -81,9 +81,7 @@ class DownloadController @Inject() ( case Some((api, _, VersionVisibility(ApiAccessType.INTERNAL, false, _))) => redirectToLoginPage(api.serviceName) - // NB - Turning off the check for being logged in when downloading a resource to avoid the need to be logging in when fetching publicly viewable OAS - // case Some((api, selectedVersion, VersionVisibility(_, _, true))) => - case Some((api, selectedVersion, VersionVisibility(_, _, _))) => + case Some((api, selectedVersion, VersionVisibility(_, _, _))) => downloadConnector.fetch(api.serviceName, selectedVersion.version, validResource) .map(_.fold(renderNotFoundPage)(Future.successful)) .flatten diff --git a/test/uk/gov/hmrc/apidocumentation/controllers/ApiDocumentationControllerSpec.scala b/test/uk/gov/hmrc/apidocumentation/controllers/ApiDocumentationControllerSpec.scala index e3bd0e6f..d32f20b5 100644 --- a/test/uk/gov/hmrc/apidocumentation/controllers/ApiDocumentationControllerSpec.scala +++ b/test/uk/gov/hmrc/apidocumentation/controllers/ApiDocumentationControllerSpec.scala @@ -213,43 +213,23 @@ class ApiDocumentationControllerSpec extends CommonControllerBaseSpec with PageR verifyPageRendered(pageTitle("Hello World"), bodyContains = Seq("> stable"))(result) } - // NB: These tests don't make sense in the context of CONTROLLED APIs having public OAS docs - Candidates for removal - // "display the API landing page with 'Request access' button for private trial when logged in" in new Setup { - // theUserIsLoggedIn() - // theDefinitionServiceWillReturnAnApiDefinition( - // extendedApiDefinitionWithPrincipalAndSubordinateAPIAvailability( - // serviceName, - // versionOne, - // Some(ApiAvailability(true, ApiAccessType.CONTROLLED, true, false)), - // Some(ApiAvailability(true, ApiAccessType.CONTROLLED, true, false)) - // ) - // ) - // DownloadConnectorMock.Fetch.returnsNoneIfNotFound() - - // val result = underTest.renderApiDocumentation(serviceName, versionOne)(request) - - // verifyApiDocumentationPageRendered(result) - // verifyPageRendered(pageTitle("Hello World"), bodyContains = Seq("> stable", "Request access"))(result) - // } - - // "display the API landing page with NO 'Request access' button for private trial when not logged in" in new Setup { - // theUserIsNotLoggedIn() - // theDefinitionServiceWillReturnAnApiDefinition( - // extendedApiDefinitionWithPrincipalAndSubordinateAPIAvailability( - // serviceName, - // versionOne, - // Some(ApiAvailability(true, ApiAccessType.CONTROLLED, false, false)), - // Some(ApiAvailability(true, ApiAccessType.CONTROLLED, false, false)) - // ) - // ) - // DownloadConnectorMock.Fetch.returnsNoneIfNotFound() - - // val result = underTest.renderApiDocumentation(serviceName, versionOne)(request) - - // verifyApiDocumentationPageRendered(result) - // verifyPageRendered(pageTitle("Hello World"), bodyContains = Seq("> stable"))(result) - // verifyPageDoesNotContain(texts = Seq("Request access"))(result) - // } + "display the API landing page with 'Request access' button for CONTROLLED APIs" in new Setup { + theUserIsLoggedIn() + theDefinitionServiceWillReturnAnApiDefinition( + extendedApiDefinitionWithPrincipalAndSubordinateAPIAvailability( + serviceName, + versionOne, + Some(ApiAvailability(true, ApiAccessType.CONTROLLED, true, false)), + Some(ApiAvailability(true, ApiAccessType.CONTROLLED, true, false)) + ) + ) + DownloadConnectorMock.Fetch.returnsNoneIfNotFound() + + val result = underTest.renderApiDocumentation(serviceName, versionOne)(request) + + verifyApiDocumentationPageRendered(result) + verifyPageRendered(pageTitle("Hello World"), bodyContains = Seq("> stable", "Request access"))(result) + } "display the not found page when invalid version specified" in new Setup { theUserIsLoggedIn()