diff --git a/build.sbt b/build.sbt index 11279b15..c7bf4edd 100644 --- a/build.sbt +++ b/build.sbt @@ -1,7 +1,6 @@ import sbt.Compile import sbt.Keys.cleanFiles - -val releaseVersion = sys.env.getOrElse("TAG", "0.2.3-BETA.2") +val releaseVersion = sys.env.getOrElse("TAG", "0.2.3-BETA.3") addCommandAlias("publishSmithy4Play", "smithy4play/publish") addCommandAlias("publishLocalSmithy4Play", "smithy4play/publishLocal") addCommandAlias("generateCoverage", "clean; coverage; test; coverageReport") @@ -32,10 +31,12 @@ val sharedSettings = defaultProjectSettings lazy val smithy4play = project .in(file("smithy4play")) + .enablePlugins(Smithy4sCodegenPlugin) .settings( sharedSettings, - scalaVersion := Dependencies.scalaVersion, - name := "smithy4play", + scalaVersion := Dependencies.scalaVersion, + Compile / smithy4sAllowedNamespaces := List("smithy.test"), + name := "smithy4play", scalacOptions += "-Ymacro-annotations", Compile / compile / wartremoverWarnings ++= Warts.unsafe, libraryDependencies ++= Dependencies.list diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 2af612aa..bad2e309 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,12 +6,16 @@ object Dependencies { val playVersion = "2.8.13" val typesafePlay = "com.typesafe.play" %% "play" % playVersion - val scalaVersion = "2.13.8" + val scalaVersion = "2.13.8" + val smithy4sVersion = "0.16.4" + val smithyCore = "com.disneystreaming.smithy4s" %% "smithy4s-core" % smithy4sVersion + val smithyJson = "com.disneystreaming.smithy4s" %% "smithy4s-json" % smithy4sVersion - val smithyCore = "com.disneystreaming.smithy4s" %% "smithy4s-core" % "0.16.1" + val classgraph = "io.github.classgraph" % "classgraph" % "4.8.149" + val smithyVersion = "1.24.0" - val smithyJson = "com.disneystreaming.smithy4s" %% "smithy4s-json" % "0.16.1" - val classgraph = "io.github.classgraph" % "classgraph" % "4.8.149" + val testTraits = + "software.amazon.smithy" % "smithy-protocol-test-traits" % smithyVersion val scalatestPlus = "org.scalatestplus.play" %% "scalatestplus-play" % "5.1.0" % Test @@ -20,6 +24,7 @@ object Dependencies { lazy val list = Seq( smithyCore, smithyJson, + testTraits, classgraph, scalatestPlus, typesafePlay, diff --git a/project/plugins.sbt b/project/plugins.sbt index 19ab39c2..69994479 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,6 @@ addSbtPlugin("com.codecommit" % "sbt-github-packages" % "0.5.3") addSbtPlugin("org.wartremover" % "sbt-wartremover" % "3.0.5") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") -addSbtPlugin("com.disneystreaming.smithy4s" % "smithy4s-sbt-codegen" % "0.15.2") +addSbtPlugin("com.disneystreaming.smithy4s" % "smithy4s-sbt-codegen" % "0.16.4") addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.15") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.9.3") diff --git a/smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala b/smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala index ca686573..c47d2c02 100644 --- a/smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala +++ b/smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala @@ -1,7 +1,7 @@ package de.innfactory.smithy4play import akka.util.ByteString -import cats.data.EitherT +import cats.data.{ EitherT, Validated } import play.api.mvc.{ AbstractController, ControllerComponents, @@ -13,10 +13,11 @@ import play.api.mvc.{ Results } import smithy4s.{ ByteArray, Endpoint, Interpreter } -import smithy4s.http.{ CodecAPI, HttpEndpoint, Metadata, PathParams } +import smithy4s.http.{ CaseInsensitive, CodecAPI, HttpEndpoint, Metadata, PathParams } import smithy4s.schema.Schema import cats.implicits._ import play.api.libs.json.Json +import smithy.api.{ Auth, HttpBearerAuth } import scala.concurrent.{ ExecutionContext, Future } @@ -51,6 +52,13 @@ class SmithyPlayEndpoint[F[_] <: ContextRoute[_], Op[ pathParams <- getPathParams(v1, httpEp) metadata = getMetadata(pathParams, v1) input <- getInput(request, metadata) + _ <- EitherT( + Future( + Validated + .cond(validateAuthHints(metadata), (), Smithy4PlayError("Unauthorized", 401)) + .toEither + ) + ) res <- impl(endpoint.wrap(input)) .run( RoutingContext @@ -68,6 +76,13 @@ class SmithyPlayEndpoint[F[_] <: ContextRoute[_], Op[ } .getOrElse(Action(NotFound("404"))) + private def validateAuthHints(metadata: Metadata) = { + for { + authSet <- endpoint.hints.get(Auth.tag) + _ <- authSet.value.find(_.value == HttpBearerAuth.id.show) + } yield metadata.headers.contains(CaseInsensitive("Authorization")) + }.getOrElse(true) + private def getPathParams( v1: RequestHeader, httpEp: HttpEndpoint[I] diff --git a/smithy4play/src/main/scala/de/innfactory/smithy4play/client/GenericAPIClient.scala b/smithy4play/src/main/scala/de/innfactory/smithy4play/client/GenericAPIClient.scala new file mode 100644 index 00000000..cceec985 --- /dev/null +++ b/smithy4play/src/main/scala/de/innfactory/smithy4play/client/GenericAPIClient.scala @@ -0,0 +1,42 @@ +package de.innfactory.smithy4play.client + +import de.innfactory.smithy4play.{ ClientRequest, ClientResponse } +import smithy4s.{ Service, Transformation } + +import scala.concurrent.ExecutionContext + +private class GenericAPIClient[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _]]( + service: Service[Alg, Op], + client: RequestClient +)(implicit ec: ExecutionContext) { + + private val smithyPlayClient = new SmithyPlayClient("/", service, client) + + /* Takes a service and creates a Transformation[Op, ClientRequest] */ + private def transformer(additionalHeaders: Option[Map[String, Seq[String]]]): Alg[ClientRequest] = + service.transform(this.opToResponse(additionalHeaders)) + + /* uses the SmithyPlayClient to transform a Operation to a ClientResponse */ + private def opToResponse(additionalHeaders: Option[Map[String, Seq[String]]]): Transformation[Op, ClientRequest] = + new Transformation[Op, ClientRequest] { + def apply[I, E, O, SI, SO](op: Op[I, E, O, SI, SO]): ClientResponse[O] = + smithyPlayClient.send(op, additionalHeaders) + } +} + +object GenericAPIClient { + + implicit class EnhancedGenericAPIClient[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _]](service: Service[Alg, Op]) { + def withClient( + client: RequestClient, + additionalHeaders: Option[Map[String, Seq[String]]] = None + )(implicit ec: ExecutionContext) = apply(service, additionalHeaders, client) + } + def apply[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _]]( + serviceI: Service[Alg, Op], + additionalHeaders: Option[Map[String, Seq[String]]] = None, + client: RequestClient + )(implicit ec: ExecutionContext): Alg[ClientRequest] = + new GenericAPIClient(serviceI, client).transformer(additionalHeaders) + +} diff --git a/smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClient.scala b/smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClient.scala index 920603db..64752881 100644 --- a/smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClient.scala +++ b/smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClient.scala @@ -7,8 +7,9 @@ import scala.concurrent.ExecutionContext class SmithyPlayClient[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _], F[_]]( baseUri: String, - service: smithy4s.Service[Alg, Op] -)(implicit executionContext: ExecutionContext, client: RequestClient) { + service: smithy4s.Service[Alg, Op], + client: RequestClient +)(implicit executionContext: ExecutionContext) { def send[I, E, O, SI, SO]( op: Op[I, E, O, SI, SO], @@ -19,7 +20,7 @@ class SmithyPlayClient[Alg[_[_, _, _, _, _]], Op[_, _, _, _, _], F[_]]( HttpEndpoint .cast(endpoint) .map(httpEndpoint => - new SmithyPlayClientEndpoint(endpoint, baseUri, additionalHeaders, httpEndpoint, input).send() + new SmithyPlayClientEndpoint(endpoint, baseUri, additionalHeaders, httpEndpoint, input, client).send() ) .get } diff --git a/smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClientEndpoint.scala b/smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClientEndpoint.scala index 7a1346f0..367974c1 100644 --- a/smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClientEndpoint.scala +++ b/smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClientEndpoint.scala @@ -14,8 +14,9 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O, baseUri: String, additionalHeaders: Option[Map[String, Seq[String]]], httpEndpoint: HttpEndpoint[I], - input: I -)(implicit executionContext: ExecutionContext, client: RequestClient) { + input: I, + client: RequestClient +)(implicit executionContext: ExecutionContext) { private val codecs: codecs = smithy4s.http.json.codecs(smithy4s.api.SimpleRestJson.protocol.hintMask ++ HintMask(InputOutput)) diff --git a/smithy4play/src/main/scala/de/innfactory/smithy4play/compliancetests/ComplianceClient.scala b/smithy4play/src/main/scala/de/innfactory/smithy4play/compliancetests/ComplianceClient.scala new file mode 100644 index 00000000..edb618a2 --- /dev/null +++ b/smithy4play/src/main/scala/de/innfactory/smithy4play/compliancetests/ComplianceClient.scala @@ -0,0 +1,105 @@ +package de.innfactory.smithy4play.compliancetests + +import de.innfactory.smithy4play.ClientResponse +import de.innfactory.smithy4play.client.{ SmithyPlayClientEndpointErrorResponse, SmithyPlayClientEndpointResponse } +import play.api.libs.json.Json +import smithy.test._ +import smithy4s.http.HttpEndpoint +import smithy4s.{ Document, Endpoint, GenLift, Monadic, Service } + +import scala.concurrent.duration.DurationInt +import scala.concurrent.{ Await, ExecutionContext } + +class ComplianceClient[ + Alg[_[_, _, _, _, _]], + Op[_, _, _, _, _] +]( + client: Monadic[Alg, ClientResponse] +)(implicit + service: Service[Alg, Op], + ec: ExecutionContext +) { + + private def clientRequest[I, E, O, SE, SO]( + endpoint: Endpoint[Op, I, E, O, SE, SO], + requestTestCase: Option[HttpRequestTestCase], + responseTestCase: Option[HttpResponseTestCase] + ) = { + + val inputFromDocument = Document.Decoder.fromSchema(endpoint.input) + val input = inputFromDocument.decode(requestTestCase.flatMap(_.params).getOrElse(Document.obj())).toOption.get + + val result = service + .asTransformation[GenLift[ClientResponse]#λ](client) + .apply(endpoint.wrap(input)) + .map(res => matchResponse(res, endpoint, responseTestCase)) + Await.result(result, 5.seconds) + } + + private def matchResponse[I, E, O, SE, SO]( + response: Either[SmithyPlayClientEndpointErrorResponse, SmithyPlayClientEndpointResponse[O]], + endpoint: Endpoint[Op, I, E, O, SE, SO], + responseTestCase: Option[HttpResponseTestCase] + ) = { + + val httpEp = HttpEndpoint.cast(endpoint).get + val responseStatusCode = response match { + case Left(value) => value.statusCode + case Right(value) => value.statusCode + } + val expectedStatusCode = responseTestCase.map(_.code).getOrElse(httpEp.code) + // val statusAssert = expectedStatusCode == responseStatusCode + + val outputFromDocument = Document.Decoder.fromSchema(endpoint.output) + val expectedOutput = + outputFromDocument.decode(responseTestCase.flatMap(_.params).getOrElse(Document.obj())).toOption + + // responseTestCase.forall(_ => expectedOutput == response.toOption.flatMap(_.body)) && statusAssert + ComplianceResponse( + expectedCode = expectedStatusCode, + receivedCode = responseStatusCode, + expectedBody = expectedOutput, + receivedBody = response.toOption.flatMap(_.body), + expectedError = responseTestCase match { + case Some(value) => value.body.getOrElse("") + case None => "" + }, + receivedError = response match { + case Left(value) => Json.parse(value.error).toString() + case Right(value) => "" + } + ) + } + + case class ComplianceResponse[O]( + expectedCode: Int, + receivedCode: Int, + expectedBody: Option[O], + receivedBody: Option[O], + expectedError: String, + receivedError: String + ) + + def tests(suite: Option[String] = None) = + service.endpoints.flatMap { endpoint => + val requests = endpoint.hints + .get(HttpRequestTests) + .map(_.value) + .getOrElse(Nil) + .filter(tc => + suite.isEmpty && tc.documentation.isEmpty || tc.documentation.getOrElse("") == suite.getOrElse("") + ) + val responses = endpoint.hints + .get(HttpResponseTests) + .map(_.value) + .getOrElse(Nil) + .filter(tc => + suite.isEmpty && tc.documentation.isEmpty || tc.documentation.getOrElse("") == suite.getOrElse("") + ) + val ids = requests.map(_.id).toSet ++ responses.map(_.id).toSet + + ids + .map(id => (requests.find(_.id == id), responses.find(_.id == id))) + .map(x => clientRequest(endpoint, x._1, x._2)) + } +} diff --git a/smithy4play/src/main/scala/de/innfactory/smithy4play/package.scala b/smithy4play/src/main/scala/de/innfactory/smithy4play/package.scala index 629a0887..11edca0d 100644 --- a/smithy4play/src/main/scala/de/innfactory/smithy4play/package.scala +++ b/smithy4play/src/main/scala/de/innfactory/smithy4play/package.scala @@ -23,6 +23,8 @@ package object smithy4play { type ClientResponse[O] = Future[Either[SmithyPlayClientEndpointErrorResponse, SmithyPlayClientEndpointResponse[O]]] + type ClientRequest[I, E, O, SI, SO] = ClientResponse[O] + type RouteResult[O] = EitherT[Future, ContextRouteError, O] type ContextRoute[O] = Kleisli[RouteResult, RoutingContext, O] diff --git a/smithy4playTest/app/controller/TestController.scala b/smithy4playTest/app/controller/TestController.scala index b5dc8cc7..fe493235 100644 --- a/smithy4playTest/app/controller/TestController.scala +++ b/smithy4playTest/app/controller/TestController.scala @@ -57,4 +57,8 @@ class TestController @Inject() (implicit override def statusCode: Int = 500 }) } + + override def testAuth(): ContextRoute[Unit] = Kleisli { rc => + EitherT.rightT[Future, ContextRouteError](()) + } } diff --git a/smithy4playTest/test/TestControllerClient.scala b/smithy4playTest/test/TestControllerClient.scala deleted file mode 100644 index cfb0bdf9..00000000 --- a/smithy4playTest/test/TestControllerClient.scala +++ /dev/null @@ -1,52 +0,0 @@ -import de.innfactory.smithy4play.ClientResponse -import de.innfactory.smithy4play.client.{ RequestClient, SmithyPlayClient } -import smithy4s.ByteArray -import testDefinitions.test.{ - BlobRequest, - BlobResponse, - QueryRequest, - SimpleTestResponse, - TestControllerService, - TestControllerServiceGen, - TestRequestBody, - TestRequestWithQueryAndPathParams, - TestWithOutputResponse -} - -import scala.concurrent.ExecutionContext - -class TestControllerClient(additionalHeaders: Map[String, Seq[String]] = Map.empty, baseUri: String = "/")(implicit - ec: ExecutionContext, - client: RequestClient -) extends TestControllerService[ClientResponse] { - - val smithyPlayClient = new SmithyPlayClient(baseUri, TestControllerService.service) - - override def test(): ClientResponse[SimpleTestResponse] = - smithyPlayClient.send(TestControllerServiceGen.Test(), Some(additionalHeaders)) - - override def testWithOutput( - pathParam: String, - testQuery: String, - testHeader: String, - body: TestRequestBody - ): ClientResponse[TestWithOutputResponse] = smithyPlayClient.send( - TestControllerServiceGen.TestWithOutput(TestRequestWithQueryAndPathParams(pathParam, testQuery, testHeader, body)), - Some(additionalHeaders ++ Map("Content-Type" -> Seq("application/json"))) - ) - - override def health(): ClientResponse[Unit] = - smithyPlayClient.send(TestControllerServiceGen.Health(), Some(additionalHeaders)) - - override def testWithBlob(body: ByteArray, contentType: String): ClientResponse[BlobResponse] = - smithyPlayClient.send( - TestControllerServiceGen.TestWithBlob(BlobRequest(body, contentType)), - Some(additionalHeaders) - ) - - override def testWithQuery(testQuery: String): ClientResponse[Unit] = - smithyPlayClient.send(TestControllerServiceGen.TestWithQuery(QueryRequest(testQuery)), Some(additionalHeaders)) - - override def testThatReturnsError(): ClientResponse[Unit] = - smithyPlayClient.send(TestControllerServiceGen.TestThatReturnsError(), Some(additionalHeaders)) -} diff --git a/smithy4playTest/test/TestControllerTest.scala b/smithy4playTest/test/TestControllerTest.scala index c5577181..3807d6e0 100644 --- a/smithy4playTest/test/TestControllerTest.scala +++ b/smithy4playTest/test/TestControllerTest.scala @@ -1,14 +1,17 @@ -import de.innfactory.smithy4play.client.{RequestClient, SmithyClientResponse} +import de.innfactory.smithy4play.ClientRequest +import de.innfactory.smithy4play.client.GenericAPIClient.EnhancedGenericAPIClient +import de.innfactory.smithy4play.client.{ GenericAPIClient, RequestClient, SmithyClientResponse } import de.innfactory.smithy4play.client.SmithyPlayTestUtils._ -import org.scalatestplus.play.{BaseOneAppPerSuite, FakeApplicationFactory, PlaySpec} +import de.innfactory.smithy4play.compliancetests.ComplianceClient +import org.scalatestplus.play.{ BaseOneAppPerSuite, FakeApplicationFactory, PlaySpec } import play.api.Application import play.api.Play.materializer import play.api.inject.guice.GuiceApplicationBuilder -import play.api.libs.json.{Json, OWrites} -import play.api.mvc.{AnyContentAsEmpty, Result} +import play.api.libs.json.{ Json, OWrites } +import play.api.mvc.{ AnyContentAsEmpty, Result } import play.api.test.FakeRequest import play.api.test.Helpers._ -import testDefinitions.test.TestRequestBody +import testDefinitions.test.{ SimpleTestResponse, TestControllerServiceGen, TestRequestBody } import smithy4s.ByteArray import java.io.File @@ -44,21 +47,32 @@ class TestControllerTest extends PlaySpec with BaseOneAppPerSuite with FakeAppli headersWithContentType = if (contentType.isDefined) headers + ("Content-Type" -> Seq(contentType.get)) else headers } yield SmithyClientResponse(bodyConsumed, headersWithContentType, result.header.status) - } } - val testControllerClient = new TestControllerClient() + val genericClient = TestControllerServiceGen.withClient(FakeRequestClient) override def fakeApplication(): Application = new GuiceApplicationBuilder().build() "controller.TestController" must { - "route to Test Endpoint" in { + "new autoTest test" in { + new ComplianceClient(genericClient).tests().map { result => + result.expectedCode mustBe result.receivedCode + result.expectedBody mustBe result.receivedBody + } + } - val result = testControllerClient.test().awaitRight + "autoTest 500" in { + new ComplianceClient(genericClient).tests(Some("500")).map { result => + result.expectedCode must not be result.receivedCode + result.receivedError mustBe result.expectedError + } + } + "route to Test Endpoint" in { + val result = genericClient.test().awaitRight result.statusCode mustBe result.expectedStatusCode } @@ -67,7 +81,7 @@ class TestControllerTest extends PlaySpec with BaseOneAppPerSuite with FakeAppli val testQuery = "thisIsATestQuery" val testHeader = "thisIsATestHeader" val body = TestRequestBody("thisIsARequestBody") - val result = testControllerClient.testWithOutput(pathParam, testQuery, testHeader, body).awaitRight + val result = genericClient.testWithOutput(pathParam, testQuery, testHeader, body).awaitRight val responseBody = result.body.get result.statusCode mustBe result.expectedStatusCode @@ -107,15 +121,15 @@ class TestControllerTest extends PlaySpec with BaseOneAppPerSuite with FakeAppli } "route to Health Endpoint" in { - val result = testControllerClient.health().awaitRight + val result = genericClient.health().awaitRight result.statusCode mustBe result.expectedStatusCode } "route to error Endpoint" in { - val result = testControllerClient.testThatReturnsError().awaitLeft + val result = genericClient.testThatReturnsError().awaitLeft - result.toErrorResponse.message must include ("fail") + result.toErrorResponse.message must include("fail") result.statusCode mustBe 500 } @@ -123,10 +137,16 @@ class TestControllerTest extends PlaySpec with BaseOneAppPerSuite with FakeAppli val path = getClass.getResource("/testPicture.png").getPath val file = new File(path) val pngAsBytes = ByteArray(Files.readAllBytes(file.toPath)) - val result = testControllerClient.testWithBlob(pngAsBytes, "image/png").awaitRight + val result = genericClient.testWithBlob(pngAsBytes, "image/png").awaitRight result.statusCode mustBe result.expectedStatusCode pngAsBytes mustBe result.body.get.body } + + "route to Auth Test" in { + val result = genericClient.testAuth().awaitLeft + + result.statusCode mustBe 401 + } } } diff --git a/smithy4playTest/testSpecs/200TestSuite.smithy b/smithy4playTest/testSpecs/200TestSuite.smithy new file mode 100644 index 00000000..05a6121f --- /dev/null +++ b/smithy4playTest/testSpecs/200TestSuite.smithy @@ -0,0 +1,37 @@ +$version: "2" + +namespace testDefinitions.test + +use smithy4s.api#simpleRestJson +use smithy.test#httpRequestTests +use smithy.test#httpResponseTests + +apply TestWithQuery @httpRequestTests([ + { + id: "test1", + method: "GET", + uri: "/query", + protocol: simpleRestJson, + params: { + "testQuery": "Hello there" + }, + } +]) +apply TestWithQuery @httpResponseTests([ + { + id: "test1", + protocol: simpleRestJson, + code: 200 + } +]) + +apply Test @httpResponseTests([ + { + id: "test2", + protocol: simpleRestJson, + params: { + message: "TestWithSimpleResponse" + }, + code: 200 + } +]) \ No newline at end of file diff --git a/smithy4playTest/testSpecs/500TestSuite.smithy b/smithy4playTest/testSpecs/500TestSuite.smithy new file mode 100644 index 00000000..8533ae61 --- /dev/null +++ b/smithy4playTest/testSpecs/500TestSuite.smithy @@ -0,0 +1,29 @@ +$version: "2" + +namespace testDefinitions.test + +use smithy4s.api#simpleRestJson +use smithy.test#httpRequestTests +use smithy.test#httpResponseTests + + +apply TestThatReturnsError @httpRequestTests([ + { + id: "test3", + method: "GET", + uri: "/error", + protocol: simpleRestJson, + documentation: "500", + code: 200 + } +]) + +apply TestThatReturnsError @httpResponseTests([ + { + id: "test3", + protocol: simpleRestJson, + body: "{\"message\":\"this is supposed to fail\"}", + documentation: "500", + code: 200 + } +]) \ No newline at end of file diff --git a/smithy4playTest/testSpecs/TestController.smithy b/smithy4playTest/testSpecs/TestController.smithy index f0af01eb..c0667781 100644 --- a/smithy4playTest/testSpecs/TestController.smithy +++ b/smithy4playTest/testSpecs/TestController.smithy @@ -3,24 +3,25 @@ namespace testDefinitions.test use smithy4s.api#simpleRestJson - +@httpBearerAuth @simpleRestJson service TestControllerService { version: "0.0.1", - operations: [Test, TestWithOutput, Health, TestWithBlob, TestWithQuery, TestThatReturnsError] + operations: [Test, TestWithOutput, Health, TestWithBlob, TestWithQuery, TestThatReturnsError, TestAuth] } +@auth([]) @http(method: "POST", uri: "/blob", code: 200) operation TestWithBlob { input: BlobRequest, output: BlobResponse } - +@auth([]) @readonly @http(method: "GET", uri: "/error", code: 200) operation TestThatReturnsError { } - +@auth([]) @readonly @http(method: "GET", uri: "/query", code: 200) operation TestWithQuery { @@ -52,17 +53,20 @@ structure BlobResponse { contentType: String } +@auth([]) @readonly @http(method: "GET", uri: "/health", code: 200) operation Health { } +@auth([]) @readonly @http(method: "GET", uri: "/", code: 200) operation Test { output: SimpleTestResponse } +@auth([]) @http(method: "POST", uri: "/test/{pathParam}", code: 200) operation TestWithOutput { input: TestRequestWithQueryAndPathParams, @@ -111,3 +115,10 @@ structure TestResponseBody { } +@auth([httpBearerAuth]) +@http(method: "GET", uri: "/auth", code: 200) +operation TestAuth { + +} + +