diff --git a/build.sbt b/build.sbt index f11c4d8..b9f1dc8 100644 --- a/build.sbt +++ b/build.sbt @@ -10,6 +10,8 @@ lazy val root = (project in file(".")) libraryDependencies ++= Seq( authUtils, catsEffect, + generatedGraphql, + graphqlClient, http4sCirce, http4sDsl, http4sEmberServer, diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8a9f238..990405e 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -9,6 +9,9 @@ object Dependencies { lazy val catsEffect = "org.typelevel" %% "cats-effect" % "3.5.4" + lazy val generatedGraphql = "uk.gov.nationalarchives" %% "tdr-generated-graphql" % "0.0.372" + lazy val graphqlClient = "uk.gov.nationalarchives" %% "tdr-graphql-client" % "0.0.144" + lazy val http4sCirce = "org.http4s" %% "http4s-circe" % http4sVersion lazy val http4sEmberServer = "org.http4s" %% "http4s-ember-server" % http4sVersion lazy val http4sDsl = "org.http4s" %% "http4s-dsl" % http4sVersion diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 42177c6..df2819a 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -1,4 +1,6 @@ api { + url = "https://api.tdr-integration.nationalarchives.gov.uk/graphql" + url = ${?API_URL} port = "8080" port = ${?API_PORT} } diff --git a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/Config.scala b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/ApplicationConfig.scala similarity index 69% rename from src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/Config.scala rename to src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/ApplicationConfig.scala index 5de7730..1e7a94b 100644 --- a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/Config.scala +++ b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/ApplicationConfig.scala @@ -1,7 +1,7 @@ package uk.gov.nationalarchives.tdr.transfer.service -object Config { - case class Api(port: Int) +object ApplicationConfig { + case class Api(port: Int, url: String) case class Auth(url: String, realm: String) case class Configuration(auth: Auth, api: Api) diff --git a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/TransferServiceServer.scala b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/TransferServiceServer.scala index c16d6a9..35930a2 100644 --- a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/TransferServiceServer.scala +++ b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/TransferServiceServer.scala @@ -12,9 +12,12 @@ import org.http4s.{HttpRoutes, Request, Response} import pureconfig.ConfigSource import pureconfig.generic.auto._ import sttp.apispec.openapi.Info +import sttp.client3.quick.backend +import sttp.client3.{HttpURLConnectionBackend, Identity, SttpBackend} import sttp.tapir.server.http4s.Http4sServerInterpreter import sttp.tapir.swagger.bundle.SwaggerInterpreter -import uk.gov.nationalarchives.tdr.transfer.service.Config.Configuration +import uk.gov.nationalarchives.tdr.keycloak.TdrKeycloakDeployment +import uk.gov.nationalarchives.tdr.transfer.service.ApplicationConfig.Configuration import uk.gov.nationalarchives.tdr.transfer.service.api.controllers.LoadController object TransferServiceServer extends IOApp { @@ -23,6 +26,12 @@ object TransferServiceServer extends IOApp { case Right(value) => value } + private val authUrl = config.auth.url + private val realm = config.auth.realm + + implicit val backend: SttpBackend[Identity, Any] = HttpURLConnectionBackend() + implicit val keycloakDeployment: TdrKeycloakDeployment = TdrKeycloakDeployment(s"$authUrl", realm, 8080) + private val apiPort: Port = Port.fromInt(config.api.port).getOrElse(port"8080") private val infoTitle = "TDR Transfer Service API" @@ -44,7 +53,7 @@ object TransferServiceServer extends IOApp { private val app: Kleisli[IO, Request[IO], Response[IO]] = allRoutes.orNotFound - private val finalApp = Logger.httpApp(true, true)(app) + private val finalApp = Logger.httpApp(logHeaders = true, logBody = true)(app) private val transferServiceServer = EmberServerBuilder .default[IO] diff --git a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/auth/TokenAuthenticator.scala b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/auth/TokenAuthenticator.scala index f873a44..c852bc1 100644 --- a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/auth/TokenAuthenticator.scala +++ b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/auth/TokenAuthenticator.scala @@ -2,7 +2,7 @@ package uk.gov.nationalarchives.tdr.transfer.service.api.auth import cats.effect.IO import uk.gov.nationalarchives.tdr.keycloak.{KeycloakUtils, TdrKeycloakDeployment, Token} -import uk.gov.nationalarchives.tdr.transfer.service.Config.Configuration +import uk.gov.nationalarchives.tdr.transfer.service.ApplicationConfig.Configuration import uk.gov.nationalarchives.tdr.transfer.service.api.errors.BackendException.AuthenticationError import scala.concurrent.ExecutionContext diff --git a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/controllers/BaseController.scala b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/controllers/BaseController.scala index ff7a320..39e98b5 100644 --- a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/controllers/BaseController.scala +++ b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/controllers/BaseController.scala @@ -7,7 +7,7 @@ import sttp.model.StatusCode import sttp.tapir.json.circe.jsonBody import sttp.tapir.server.PartialServerEndpoint import sttp.tapir.{Endpoint, auth, endpoint, statusCode} -import uk.gov.nationalarchives.tdr.transfer.service.Config.Configuration +import uk.gov.nationalarchives.tdr.transfer.service.ApplicationConfig.Configuration import uk.gov.nationalarchives.tdr.transfer.service.api.auth.{AuthenticatedContext, TokenAuthenticator} import uk.gov.nationalarchives.tdr.transfer.service.api.errors.BackendException.AuthenticationError import uk.gov.nationalarchives.tdr.transfer.service.api.model.Serializers._ diff --git a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/controllers/LoadController.scala b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/controllers/LoadController.scala index d88b8c4..4a1b1bb 100644 --- a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/controllers/LoadController.scala +++ b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/controllers/LoadController.scala @@ -2,31 +2,43 @@ package uk.gov.nationalarchives.tdr.transfer.service.api.controllers import cats.effect.IO import org.http4s.HttpRoutes -import sttp.tapir.{Endpoint, _} +import sttp.client3.{Identity, SttpBackend} +import sttp.tapir._ import sttp.tapir.json.circe.jsonBody import sttp.tapir.server.PartialServerEndpoint import sttp.tapir.server.http4s.Http4sServerInterpreter +import uk.gov.nationalarchives.tdr.keycloak.TdrKeycloakDeployment import uk.gov.nationalarchives.tdr.transfer.service.api.auth.AuthenticatedContext import uk.gov.nationalarchives.tdr.transfer.service.api.errors.BackendException -import uk.gov.nationalarchives.tdr.transfer.service.api.model.Consignment.ConsignmentDetails +import uk.gov.nationalarchives.tdr.transfer.service.api.model.LoadModel.{AWSS3LoadDestination, LoadDetails} import uk.gov.nationalarchives.tdr.transfer.service.api.model.Serializers._ -import uk.gov.nationalarchives.tdr.transfer.service.services.ConsignmentService +import uk.gov.nationalarchives.tdr.transfer.service.services.GraphQlApiService -class LoadController(consignmentService: ConsignmentService) extends BaseController { - def endpoints: List[Endpoint[String, Unit, BackendException.AuthenticationError, ConsignmentDetails, Any]] = List(initiateLoadEndpoint.endpoint) +import java.util.UUID + +class LoadController(graphqlApiService: GraphQlApiService) extends BaseController { + def endpoints: List[Endpoint[String, Unit, BackendException.AuthenticationError, LoadDetails, Any]] = List(initiateLoadEndpoint.endpoint) def routes: HttpRoutes[IO] = initiateLoadRoute - val initiateLoadEndpoint: PartialServerEndpoint[String, AuthenticatedContext, Unit, BackendException.AuthenticationError, ConsignmentDetails, Any, IO] = securedWithBearer + private val initiateLoadEndpoint: PartialServerEndpoint[String, AuthenticatedContext, Unit, BackendException.AuthenticationError, LoadDetails, Any, IO] = securedWithBearer .summary("Initiate the load of records and metadata") .post .in("load" / "sharepoint" / "initiate") - .out(jsonBody[ConsignmentDetails]) + .out(jsonBody[LoadDetails]) + + private def loadDetails(consignmentId: UUID): IO[LoadDetails] = { + val recordsS3Bucket = AWSS3LoadDestination("s3BucketNameRecords", "s3BucketKeyRecords") + val metadataS3Bucket = AWSS3LoadDestination("s3BucketNameMetadata", "s3BucketKeyMetadata") + IO(LoadDetails(consignmentId, recordsLoadDestination = recordsS3Bucket, metadataLoadDestination = metadataS3Bucket)) + } val initiateLoadRoute: HttpRoutes[IO] = - Http4sServerInterpreter[IO]().toRoutes(initiateLoadEndpoint.serverLogicSuccess(ac => _ => consignmentService.createConsignment(ac.token))) + Http4sServerInterpreter[IO]().toRoutes( + initiateLoadEndpoint.serverLogicSuccess(ac => _ => graphqlApiService.createConsignment(ac.token).flatMap(c => loadDetails(c.consignmentid.get))) + ) } object LoadController { - def apply() = new LoadController(ConsignmentService.apply()) + def apply()(implicit backend: SttpBackend[Identity, Any], keycloakDeployment: TdrKeycloakDeployment) = new LoadController(GraphQlApiService.apply()) } diff --git a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/model/Consignment.scala b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/model/Consignment.scala deleted file mode 100644 index 462a6c4..0000000 --- a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/model/Consignment.scala +++ /dev/null @@ -1,9 +0,0 @@ -package uk.gov.nationalarchives.tdr.transfer.service.api.model - -import java.util.UUID - -sealed trait ConsignmentModel - -object Consignment { - case class ConsignmentDetails(consignmentId: UUID) extends ConsignmentModel -} diff --git a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/model/LoadModel.scala b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/model/LoadModel.scala new file mode 100644 index 0000000..a34a5b8 --- /dev/null +++ b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/api/model/LoadModel.scala @@ -0,0 +1,11 @@ +package uk.gov.nationalarchives.tdr.transfer.service.api.model + +import java.util.UUID + +sealed trait LoadModel +sealed trait LoadDestinationModel + +object LoadModel { + case class AWSS3LoadDestination(bucketName: String, bucketKey: String) extends LoadDestinationModel + case class LoadDetails(consignmentId: UUID, recordsLoadDestination: AWSS3LoadDestination, metadataLoadDestination: AWSS3LoadDestination) extends LoadModel +} diff --git a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/services/ConsignmentService.scala b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/services/ConsignmentService.scala deleted file mode 100644 index 965b497..0000000 --- a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/services/ConsignmentService.scala +++ /dev/null @@ -1,19 +0,0 @@ -package uk.gov.nationalarchives.tdr.transfer.service.services - -import cats.effect.IO -import cats.implicits.catsSyntaxApplicativeId -import uk.gov.nationalarchives.tdr.keycloak.Token -import uk.gov.nationalarchives.tdr.transfer.service.api.model.Consignment.ConsignmentDetails - -import java.util.UUID - -class ConsignmentService { - def createConsignment(token: Token): IO[ConsignmentDetails] = { - // For now just return dummy response - ConsignmentDetails(UUID.fromString("ae4b7cad-ee83-46bd-b952-80bc8263c6c2")).pure[IO] - } -} - -object ConsignmentService { - def apply() = new ConsignmentService -} diff --git a/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/services/GraphQlApiService.scala b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/services/GraphQlApiService.scala new file mode 100644 index 0000000..d61035a --- /dev/null +++ b/src/main/scala/uk/gov/nationalarchives/tdr/transfer/service/services/GraphQlApiService.scala @@ -0,0 +1,39 @@ +package uk.gov.nationalarchives.tdr.transfer.service.services + +import cats.effect.IO +import cats.implicits.{catsSyntaxApplicativeId, catsSyntaxOptionId} +import com.typesafe.scalalogging.Logger +import graphql.codegen.AddConsignment +import sttp.client3.{Identity, SttpBackend} +import uk.gov.nationalarchives.tdr.GraphQLClient +import graphql.codegen.AddConsignment.{addConsignment => ac} +import graphql.codegen.types.AddConsignmentInput +import uk.gov.nationalarchives.tdr.keycloak.{TdrKeycloakDeployment, Token} +import uk.gov.nationalarchives.tdr.transfer.service.api.model.LoadModel.LoadDetails + +import java.util.UUID +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent.Future + +class GraphQlApiService()(implicit keycloakDeployment: TdrKeycloakDeployment, backend: SttpBackend[Identity, Any]) { + + implicit class FutureUtils[T](f: Future[T]) { + def toIO: IO[T] = IO.fromFuture(IO(f)) + } + + private val addConsignmentClient = new GraphQLClient[ac.Data, ac.Variables]("apiUrl") + + def createConsignment(token: Token): IO[AddConsignment.addConsignment.AddConsignment] = { + for { + result <- addConsignmentClient.getResult(token.bearerAccessToken, ac.document, ac.Variables(AddConsignmentInput(None, "standard")).some).toIO + data = result.data.get + } yield data.addConsignment + } +} + +object GraphQlApiService { + def apply()(implicit + backend: SttpBackend[Identity, Any], + keycloakDeployment: TdrKeycloakDeployment + ) = new GraphQlApiService +} diff --git a/src/test/resources/application.conf b/src/test/resources/application.conf index 9ab2156..361cddc 100644 --- a/src/test/resources/application.conf +++ b/src/test/resources/application.conf @@ -1,5 +1,6 @@ api { port = "8080" + url = "http://localhost:9001/graphql" } auth { diff --git a/src/test/resources/json/add_consignment_response.json b/src/test/resources/json/add_consignment_response.json new file mode 100644 index 0000000..5b07013 --- /dev/null +++ b/src/test/resources/json/add_consignment_response.json @@ -0,0 +1,9 @@ +{ + "data": { + "addConsignment": { + "consignmentid": "6e3b76c4-1745-4467-8ac5-b4dd736e1b3e", + "userid": "4ab14990-ed63-4615-8336-56fbb9960300", + "consignmentType": "standard" + } + } +} \ No newline at end of file diff --git a/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/TestUtils.scala b/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/TestUtils.scala index 71527e8..bca45fc 100644 --- a/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/TestUtils.scala +++ b/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/TestUtils.scala @@ -8,7 +8,7 @@ import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import pureconfig.ConfigSource import pureconfig.generic.auto._ -import uk.gov.nationalarchives.tdr.transfer.service.Config.Configuration +import uk.gov.nationalarchives.tdr.transfer.service.ApplicationConfig.Configuration import java.util.UUID diff --git a/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/api/TransferServiceServerSpec.scala b/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/api/TransferServiceServerSpec.scala index 4cf19a5..5db05c2 100644 --- a/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/api/TransferServiceServerSpec.scala +++ b/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/api/TransferServiceServerSpec.scala @@ -10,10 +10,17 @@ import org.http4s.{Header, Headers, Method, Request, Status} import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import org.typelevel.ci.CIString +import sttp.client3.{HttpURLConnectionBackend, Identity, SttpBackend} +import uk.gov.nationalarchives.tdr.keycloak.TdrKeycloakDeployment import uk.gov.nationalarchives.tdr.transfer.service.TestUtils.{invalidToken, validUserToken} import uk.gov.nationalarchives.tdr.transfer.service.api.controllers.LoadController +import scala.concurrent.ExecutionContextExecutor + class TransferServiceServerSpec extends AnyFlatSpec with Matchers { + implicit val executionContext: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global + implicit val backend: SttpBackend[Identity, Any] = HttpURLConnectionBackend() + implicit val tdrKeycloakDeployment: TdrKeycloakDeployment = TdrKeycloakDeployment("authUrl", "realm", 60) "'healthcheck' endpoint" should "return 200 if server running" in { val getHealthCheck = Request[IO](Method.GET, uri"/healthcheck") diff --git a/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/services/ConsignmentServiceSpec.scala b/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/services/ConsignmentServiceSpec.scala deleted file mode 100644 index d3b1e45..0000000 --- a/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/services/ConsignmentServiceSpec.scala +++ /dev/null @@ -1,19 +0,0 @@ -package uk.gov.nationalarchives.tdr.transfer.service.services - -import cats.effect.unsafe.implicits.global -import org.mockito.MockitoSugar.mock -import org.scalatest.flatspec.AnyFlatSpec -import org.scalatest.matchers.should.Matchers -import uk.gov.nationalarchives.tdr.keycloak.Token - -import java.util.UUID - -class ConsignmentServiceSpec extends AnyFlatSpec with Matchers { - val mockKeycloakToken: Token = mock[Token] - - "'createConsignment'" should "return the consignment id of the created consignment" in { - val response = ConsignmentService.apply().createConsignment(mockKeycloakToken).unsafeRunSync() - - response.consignmentId shouldBe UUID.fromString("ae4b7cad-ee83-46bd-b952-80bc8263c6c2") - } -} diff --git a/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/services/ExternalServicesSpec.scala b/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/services/ExternalServicesSpec.scala new file mode 100644 index 0000000..1a0986c --- /dev/null +++ b/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/services/ExternalServicesSpec.scala @@ -0,0 +1,91 @@ +package uk.gov.nationalarchives.tdr.transfer.service.services + +import com.github.tomakehurst.wiremock.WireMockServer +import com.github.tomakehurst.wiremock.client.WireMock._ +import com.github.tomakehurst.wiremock.stubbing.StubMapping +import org.scalatest.concurrent.ScalaFutures +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers +import org.scalatest.time.{Millis, Seconds, Span} +import org.scalatest.{BeforeAndAfterAll, BeforeAndAfterEach} + +import java.io.File +import scala.io.Source.fromResource +import scala.reflect.io.Directory + +class ExternalServicesSpec extends AnyFlatSpec with BeforeAndAfterEach with BeforeAndAfterAll with ScalaFutures { + override implicit def patienceConfig: PatienceConfig = PatienceConfig(timeout = scaled(Span(5, Seconds)), interval = scaled(Span(100, Millis))) + + val wiremockGraphqlServer = new WireMockServer(9001) + val wiremockAuthServer = new WireMockServer(9002) +// val wiremockSsmServer = new WireMockServer(9004) +// val wiremockS3 = new WireMockServer(8003) + +// def setupSsmServer(): Unit = { +// wiremockSsmServer +// .stubFor( +// post(urlEqualTo("/")) +// .willReturn(okJson("{\"Parameter\":{\"Name\":\"string\",\"Value\":\"string\"}}")) +// ) +// } + + val graphQlPath = "/graphql" + val authPath = "/auth/realms/tdr/protocol/openid-connect/token" + + def graphQlUrl: String = wiremockGraphqlServer.url(graphQlPath) + + def graphqlOkJson(saveMetadata: Boolean = false): Unit = { + wiremockGraphqlServer.stubFor( + post(urlEqualTo(graphQlPath)) + .withRequestBody(containing("addConsignment")) + .willReturn(okJson(fromResource(s"json/add_consignment_response.json").mkString)) + ) + + wiremockGraphqlServer.stubFor( + post(urlEqualTo(graphQlPath)) + .withRequestBody(containing("displayProperties")) + .willReturn(okJson(fromResource(s"json/display_properties.json").mkString)) + ) + + wiremockGraphqlServer.stubFor( + post(urlEqualTo(graphQlPath)) + .withRequestBody(containing("updateConsignmentStatus")) + .willReturn(ok("""{"data": {"updateConsignmentStatus": 1}}""".stripMargin)) + ) + if (saveMetadata) { + wiremockGraphqlServer.stubFor( + post(urlEqualTo(graphQlPath)) + .withRequestBody(containing("addOrUpdateBulkFileMetadata")) + .willReturn(ok("""{"data": {"addOrUpdateBulkFileMetadata": []}}""".stripMargin)) + ) + } + } + + def authOkJson(): StubMapping = wiremockAuthServer.stubFor( + post(urlEqualTo(authPath)) + .willReturn(okJson("""{"access_token": "abcde"}""")) + ) + + def authUnavailable: StubMapping = wiremockAuthServer.stubFor(post(urlEqualTo(authPath)).willReturn(serverError())) + + def graphqlUnavailable: StubMapping = wiremockGraphqlServer.stubFor(post(urlEqualTo(graphQlPath)).willReturn(serverError())) + + override def beforeAll(): Unit = { + wiremockGraphqlServer.start() + wiremockAuthServer.start() + } + + override def afterAll(): Unit = { + wiremockGraphqlServer.stop() + wiremockAuthServer.stop() + } + + override def afterEach(): Unit = { + wiremockAuthServer.resetAll() + wiremockGraphqlServer.resetAll() + val runningFiles = new File(s"./src/test/resources/testfiles/running-files/") + if (runningFiles.exists()) { + new Directory(runningFiles).deleteRecursively() + } + } +} diff --git a/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/services/GraphQlApiServiceSpec.scala b/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/services/GraphQlApiServiceSpec.scala new file mode 100644 index 0000000..4c93dab --- /dev/null +++ b/src/test/scala/uk/gov/nationalarchives/tdr/transfer/service/services/GraphQlApiServiceSpec.scala @@ -0,0 +1,37 @@ +package uk.gov.nationalarchives.tdr.transfer.service.services + +import cats.effect.unsafe.implicits.global +import com.nimbusds.oauth2.sdk.token.BearerAccessToken +import org.mockito.ArgumentMatchers.any +import org.mockito.MockitoSugar.{doAnswer, mock} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers +import sttp.client3.{HttpURLConnectionBackend, Identity, SttpBackend} +import uk.gov.nationalarchives.tdr.keycloak.{KeycloakUtils, TdrKeycloakDeployment, Token} + +import java.util.UUID +import scala.concurrent.{ExecutionContextExecutor, Future} +import scala.reflect.ClassTag + +class GraphQlApiServiceSpec extends ExternalServicesSpec with Matchers { + implicit val executionContext: ExecutionContextExecutor = scala.concurrent.ExecutionContext.global + implicit val backend: SttpBackend[Identity, Any] = HttpURLConnectionBackend() + implicit val tdrKeycloakDeployment: TdrKeycloakDeployment = TdrKeycloakDeployment("authUrl", "realm", 60) + + val mockKeycloakToken: Token = mock[Token] + val keycloak = mock[KeycloakUtils] + + "'createConsignment'" should "return the consignment id of the created consignment" in { + doAnswer(() => new BearerAccessToken("token")) + .when(mockKeycloakToken) + .bearerAccessToken + + doAnswer(() => Future(new BearerAccessToken("token"))) + .when(keycloak) + .serviceAccountToken[Identity](any[String], any[String])(any[SttpBackend[Identity, Any]], any[ClassTag[Identity[_]]], any[TdrKeycloakDeployment]) + + val response = GraphQlApiService.apply().createConsignment(mockKeycloakToken).unsafeRunSync() + + response.consignmentid.get shouldBe UUID.fromString("ae4b7cad-ee83-46bd-b952-80bc8263c6c2") + } +}