Skip to content

Commit

Permalink
APIS-6465: Allow statuses of PROTOTYPED and PUBLISHED from api-defini…
Browse files Browse the repository at this point in the history
…tion (#100)

* APIS-6465: Allow statuses of PROTOTYPED and PUBLISHED from api-definition

* APIS-6465: Add a comment and a unit test

* APIS-6465: Review comments
  • Loading branch information
johnsgp authored Oct 27, 2023
1 parent f92bde3 commit 59e9478
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 42 deletions.
49 changes: 25 additions & 24 deletions app/uk/gov/hmrc/apipublisher/models/PublisherResponse.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,41 +20,42 @@ import play.api.libs.json._

case class PublicationResult(approved: Boolean, publisherResponse: Option[PublisherResponse])

case class PublisherResponse(name: String, serviceName: String, context: String, description: String, versions: List[PartialApiVersion])
case class PublisherResponse(name: String, serviceName: String, context: String, description: String, versions: List[PublisherApiVersion])

object PublisherResponse {
implicit val format: OFormat[PublisherResponse] = Json.format[PublisherResponse]
}

case class PartialApiVersion(version: String, status: ApiStatus, endpointsEnabled: Option[Boolean])
case class PublisherApiVersion(version: String, status: PublisherApiStatus, endpointsEnabled: Option[Boolean])

object PartialApiVersion {
implicit val format: OFormat[PartialApiVersion] = Json.format[PartialApiVersion]
object PublisherApiVersion {
implicit val format: OFormat[PublisherApiVersion] = Json.format[PublisherApiVersion]
}

sealed trait ApiStatus

object ApiStatus {
case object ALPHA extends ApiStatus
case object BETA extends ApiStatus
case object STABLE extends ApiStatus
case object DEPRECATED extends ApiStatus
case object RETIRED extends ApiStatus

def apply(text: String): Option[ApiStatus] = text.toUpperCase() match {
case "ALPHA" => Some(ALPHA)
case "BETA" => Some(BETA)
case "STABLE" => Some(STABLE)
case "DEPRECATED" => Some(DEPRECATED)
case "RETIRED" => Some(RETIRED)
case _ => None
sealed trait PublisherApiStatus

object PublisherApiStatus {
case object ALPHA extends PublisherApiStatus
case object BETA extends PublisherApiStatus
case object STABLE extends PublisherApiStatus
case object DEPRECATED extends PublisherApiStatus
case object RETIRED extends PublisherApiStatus

// When the api-definition service stops returning PROTOTYPED and PUBLISHED, the conversions below can be removed
def apply(text: String): Option[PublisherApiStatus] = text.toUpperCase() match {
case "ALPHA" => Some(ALPHA)
case "PROTOTYPED" | "BETA" => Some(BETA)
case "PUBLISHED" | "STABLE" => Some(STABLE)
case "DEPRECATED" => Some(DEPRECATED)
case "RETIRED" => Some(RETIRED)
case _ => None
}

private val convert: String => JsResult[ApiStatus] = s => ApiStatus(s).fold[JsResult[ApiStatus]](JsError(s"$s is not a status"))(status => JsSuccess(status))
private val convert: String => JsResult[PublisherApiStatus] = s => PublisherApiStatus(s).fold[JsResult[PublisherApiStatus]](JsError(s"$s is not a status"))(status => JsSuccess(status))

implicit val reads: Reads[ApiStatus] = JsPath.read[String].flatMapResult(convert(_))
implicit val reads: Reads[PublisherApiStatus] = JsPath.read[String].flatMapResult(convert(_))

implicit val writes: Writes[ApiStatus] = Writes[ApiStatus](status => JsString(status.toString))
implicit val writes: Writes[PublisherApiStatus] = Writes[PublisherApiStatus](status => JsString(status.toString))

implicit val format: Format[ApiStatus] = Format(reads, writes)
implicit val format: Format[PublisherApiStatus] = Format(reads, writes)
}
14 changes: 7 additions & 7 deletions it/uk/gov/hmrc/apipublisher/PublisherFeatureSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class PublisherFeatureSpec extends BaseFeatureSpec {
| "versions": [
| {
| "version": "1.0",
| "status": "STABLE"
| "status": "PUBLISHED"
| }
| ]
| }
Expand All @@ -184,7 +184,7 @@ class PublisherFeatureSpec extends BaseFeatureSpec {
| "versions": [
| {
| "version": "1.0",
| "status": "STABLE",
| "status": "PUBLISHED",
| "fieldDefinitions": [
| {
| "name": "callbackUrl",
Expand All @@ -202,11 +202,11 @@ class PublisherFeatureSpec extends BaseFeatureSpec {
| },
| {
| "version": "2.0",
| "status": "STABLE"
| "status": "PUBLISHED"
| },
| {
| "version": "3.0",
| "status": "STABLE",
| "status": "PUBLISHED",
| "fieldDefinitions": [
| {
| "name": "callbackUrlOnly",
Expand Down Expand Up @@ -266,7 +266,7 @@ class PublisherFeatureSpec extends BaseFeatureSpec {
| "versions" : [
| {
| "version" : "1.0",
| "status" : "STABLE",
| "status" : "PUBLISHED",
| "endpoints": [
| {
| "uriPattern": "/hello",
Expand All @@ -279,7 +279,7 @@ class PublisherFeatureSpec extends BaseFeatureSpec {
| },
| {
| "version" : "2.0",
| "status" : "STABLE",
| "status" : "PUBLISHED",
| "endpoints": [
| {
| "uriPattern": "/hello",
Expand All @@ -293,7 +293,7 @@ class PublisherFeatureSpec extends BaseFeatureSpec {
| },
| {
| "version" : "3.0",
| "status" : "STABLE",
| "status" : "PUBLISHED",
| "endpoints": [
| {
| "uriPattern": "/hello",
Expand Down
4 changes: 2 additions & 2 deletions test/resources/input/api-with-endpoints-and-fields.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"access": {
"type" : "PUBLIC"
},
"status" : "STABLE",
"status" : "PUBLISHED",
"endpoints" : [
{
"uriPatter" : "/hello",
Expand Down Expand Up @@ -117,7 +117,7 @@
},
{
"version" : "3.0",
"status" : "BETA",
"status" : "PROTOTYPED",
"endpoints" : [
{
"uriPattern" : "/hello",
Expand Down
4 changes: 2 additions & 2 deletions test/resources/input/api-with-endpoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"access": {
"type" : "PUBLIC"
},
"status" : "STABLE",
"status" : "PUBLISHED",
"endpoints" : [
{
"uriPatter" : "/hello",
Expand All @@ -56,7 +56,7 @@
},
{
"version" : "3.0",
"status" : "BETA",
"status" : "PROTOTYPED",
"endpoints" : [
{
"uriPattern" : "/hello",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import uk.gov.hmrc.http.HeaderNames.xRequestId
import uk.gov.hmrc.http.{HeaderCarrier, UnprocessableEntityException}

import uk.gov.hmrc.apipublisher.exceptions.UnknownApiServiceException
import uk.gov.hmrc.apipublisher.models.ApiStatus._
import uk.gov.hmrc.apipublisher.models.PublisherApiStatus._
import uk.gov.hmrc.apipublisher.models._
import uk.gov.hmrc.apipublisher.services._
import uk.gov.hmrc.apipublisher.wiring.AppContext
Expand Down Expand Up @@ -63,7 +63,7 @@ class PublisherControllerSpec extends AsyncHmrcSpec with GuiceOneAppPerSuite wit
serviceName = "example-api",
context = "test/example",
description = "An example of an API",
versions = List(PartialApiVersion(
versions = List(PublisherApiVersion(
version = "1.0",
status = STABLE,
endpointsEnabled = Some(true)
Expand Down
59 changes: 59 additions & 0 deletions test/uk/gov/hmrc/apipublisher/models/PublisherApiStatusSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2023 HM Revenue & Customs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package uk.gov.hmrc.apipublisher.models

import utils.HmrcSpec

import play.api.libs.json.{JsResultException, Json}

import uk.gov.hmrc.apipublisher.models.PublisherApiStatus.{BETA, STABLE}

class PublisherApiStatusSpec extends HmrcSpec {

"Parsing an ApiStatus" should {
"parse STABLE correctly" in {
val status = parseStatus("STABLE")
status shouldBe STABLE
}

"parse BETA correctly" in {
val status = parseStatus("BETA")
status shouldBe BETA
}

"convert PUBLISHED to STABLE" in {
val status = parseStatus("PUBLISHED")
status shouldBe STABLE
}

"convert PROTOTYPED to BETA" in {
val status = parseStatus("PROTOTYPED")
status shouldBe BETA
}

"thrown an exception if the status is INVALID" in {
val exception = intercept[JsResultException](parseStatus("INVALID"))
exception.getMessage should include("INVALID is not a status")
}
}

private def parseStatus(status: String) = {
Json.parse(s"""{"status":"$status","version":"1.0","endpointsEnabled":true}""")
.as[PublisherApiVersion]
.status
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import uk.gov.hmrc.http.HeaderNames.xRequestId

import uk.gov.hmrc.apipublisher.connectors.{APIDefinitionConnector, APIScopeConnector, APISubscriptionFieldsConnector}
import uk.gov.hmrc.apipublisher.models
import uk.gov.hmrc.apipublisher.models.ApiStatus._
import uk.gov.hmrc.apipublisher.models.PublisherApiStatus._
import uk.gov.hmrc.apipublisher.models._

class PublisherServiceSpec extends AsyncHmrcSpec {
Expand Down Expand Up @@ -63,10 +63,10 @@ class PublisherServiceSpec extends AsyncHmrcSpec {
context = "test",
description = "Test API",
versions = List(
PartialApiVersion(version = "1.0", status = STABLE, endpointsEnabled = None),
PartialApiVersion(version = "2.0", status = STABLE, endpointsEnabled = None),
PartialApiVersion(version = "2.1", status = STABLE, endpointsEnabled = None),
PartialApiVersion(version = "3.0", status = BETA, endpointsEnabled = None)
PublisherApiVersion(version = "1.0", status = STABLE, endpointsEnabled = None),
PublisherApiVersion(version = "2.0", status = STABLE, endpointsEnabled = None),
PublisherApiVersion(version = "2.1", status = STABLE, endpointsEnabled = None),
PublisherApiVersion(version = "3.0", status = BETA, endpointsEnabled = None)
)
)

Expand Down

0 comments on commit 59e9478

Please sign in to comment.