Skip to content

Commit

Permalink
Encode opt query params correctly in open api (#3127) (#3152)
Browse files Browse the repository at this point in the history
Add tests for optional headers and payload as well
  • Loading branch information
987Nabil authored Sep 27, 2024
1 parent 40c4b6f commit ad6dac9
Show file tree
Hide file tree
Showing 2 changed files with 367 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,13 @@ object OpenAPIGenSpec extends ZIOSpecDefault {
.out[SimpleOutputBody]
.outError[NotFoundError](Status.NotFound)

private val queryParamOptEndpoint =
Endpoint(GET / "withQuery")
.in[SimpleInputBody]
.query(HttpCodec.query[String]("query").optional)
.out[SimpleOutputBody]
.outError[NotFoundError](Status.NotFound)

private val queryParamCollectionEndpoint =
Endpoint(GET / "withQuery")
.in[SimpleInputBody]
Expand All @@ -194,6 +201,19 @@ object OpenAPIGenSpec extends ZIOSpecDefault {
.out[SimpleOutputBody]
.outError[NotFoundError](Status.NotFound)

private val optionalHeaderEndpoint =
Endpoint(GET / "withHeader")
.in[SimpleInputBody]
.header(HttpCodec.contentType.optional)
.out[SimpleOutputBody]
.outError[NotFoundError](Status.NotFound)

private val optionalPayloadEndpoint =
Endpoint(GET / "withPayload")
.inCodec(HttpCodec.content[Payload].optional)
.out[SimpleOutputBody]
.outError[NotFoundError](Status.NotFound)

private val alternativeInputEndpoint =
Endpoint(GET / "inputAlternative")
.inCodec(
Expand Down Expand Up @@ -493,6 +513,134 @@ object OpenAPIGenSpec extends ZIOSpecDefault {
|}""".stripMargin
assertTrue(json == toJsonAst(expectedJson))
},
test("with optional query parameter") {
val generated = OpenAPIGen.fromEndpoints("Simple Endpoint", "1.0", queryParamOptEndpoint)
val json = toJsonAst(generated)
val expectedJson = """{
| "openapi" : "3.1.0",
| "info" : {
| "title" : "Simple Endpoint",
| "version" : "1.0"
| },
| "paths" : {
| "/withQuery" : {
| "get" : {
| "parameters" : [
|
| {
| "name" : "query",
| "in" : "query",
| "schema" :
| {
| "type" :[
| "string",
| "null"
| ]
| },
| "allowReserved" : false,
| "style" : "form"
| }
| ],
| "requestBody" :
| {
| "content" : {
| "application/json" : {
| "schema" :
| {
| "$ref" : "#/components/schemas/SimpleInputBody"
| }
| }
| },
| "required" : true
| },
| "responses" : {
| "200" :
| {
| "content" : {
| "application/json" : {
| "schema" :
| {
| "$ref" : "#/components/schemas/SimpleOutputBody"
| }
| }
| }
| },
| "404" :
| {
| "content" : {
| "application/json" : {
| "schema" :
| {
| "$ref" : "#/components/schemas/NotFoundError"
| }
| }
| }
| }
| }
| }
| }
| },
| "components" : {
| "schemas" : {
| "NotFoundError" :
| {
| "type" :
| "object",
| "properties" : {
| "message" : {
| "type" :
| "string"
| }
| },
| "required" : [
| "message"
| ]
| },
| "SimpleInputBody" :
| {
| "type" :
| "object",
| "properties" : {
| "name" : {
| "type" :
| "string"
| },
| "age" : {
| "type" :
| "integer",
| "format" : "int32"
| }
| },
| "required" : [
| "name",
| "age"
| ]
| },
| "SimpleOutputBody" :
| {
| "type" :
| "object",
| "properties" : {
| "userName" : {
| "type" :
| "string"
| },
| "score" : {
| "type" :
| "integer",
| "format" : "int32"
| }
| },
| "required" : [
| "userName",
| "score"
| ]
| }
| }
| }
|}""".stripMargin
assertTrue(json == toJsonAst(expectedJson))
},
test("with query parameter with multiple values") {
val generated = OpenAPIGen.fromEndpoints("Simple Endpoint", "1.0", queryParamCollectionEndpoint)
val json = toJsonAst(generated)
Expand Down Expand Up @@ -749,6 +897,214 @@ object OpenAPIGenSpec extends ZIOSpecDefault {
|}""".stripMargin
assertTrue(json == toJsonAst(expectedJson))
},
test("optional header") {
val generated = OpenAPIGen.fromEndpoints("Simple Endpoint", "1.0", optionalHeaderEndpoint)
val json = toJsonAst(generated)
val expectedJson = """{
| "openapi" : "3.1.0",
| "info" : {
| "title" : "Simple Endpoint",
| "version" : "1.0"
| },
| "paths" : {
| "/withHeader" : {
| "get" : {
| "parameters" : [
| {
| "name" : "content-type",
| "in" : "header",
| "schema" : {
| "type" : [
| "string",
| "null"
| ]
| },
| "style" : "simple"
| }
| ],
| "requestBody" : {
| "content" : {
| "application/json" : {
| "schema" : {
| "$ref" : "#/components/schemas/SimpleInputBody",
| "description" : ""
| }
| }
| },
| "required" : true
| },
| "responses" : {
| "200" : {
| "content" : {
| "application/json" : {
| "schema" : {
| "$ref" : "#/components/schemas/SimpleOutputBody"
| }
| }
| }
| },
| "404" : {
| "content" : {
| "application/json" : {
| "schema" : {
| "$ref" : "#/components/schemas/NotFoundError"
| }
| }
| }
| }
| }
| }
| }
| },
| "components" : {
| "schemas" : {
| "NotFoundError" : {
| "type" : "object",
| "properties" : {
| "message" : {
| "type" : "string"
| }
| },
| "required" : [
| "message"
| ]
| },
| "SimpleInputBody" : {
| "type" : "object",
| "properties" : {
| "name" : {
| "type" : "string"
| },
| "age" : {
| "type" : "integer",
| "format" : "int32"
| }
| },
| "required" : [
| "name",
| "age"
| ]
| },
| "SimpleOutputBody" : {
| "type" : "object",
| "properties" : {
| "userName" : {
| "type" : "string"
| },
| "score" : {
| "type" : "integer",
| "format" : "int32"
| }
| },
| "required" : [
| "userName",
| "score"
| ]
| }
| }
| }
|}""".stripMargin
assertTrue(json == toJsonAst(expectedJson))
},
test("optional payload") {
val generated = OpenAPIGen.fromEndpoints("Simple Endpoint", "1.0", optionalPayloadEndpoint)
val json = toJsonAst(generated)
val expected = """{
| "openapi" : "3.1.0",
| "info" : {
| "title" : "Simple Endpoint",
| "version" : "1.0"
| },
| "paths" : {
| "/withPayload" : {
| "get" : {
| "requestBody" : {
| "content" : {
| "application/json" : {
| "schema" : {
| "anyOf" : [
| {
| "type" : "null"
| },
| {
| "$ref" : "#/components/schemas/Payload"
| }
| ],
| "description" : ""
| }
| }
| },
| "required" : false
| },
| "responses" : {
| "200" : {
| "content" : {
| "application/json" : {
| "schema" : {
| "$ref" : "#/components/schemas/SimpleOutputBody"
| }
| }
| }
| },
| "404" : {
| "content" : {
| "application/json" : {
| "schema" : {
| "$ref" : "#/components/schemas/NotFoundError"
| }
| }
| }
| }
| }
| }
| }
| },
| "components" : {
| "schemas" : {
| "NotFoundError" : {
| "type" : "object",
| "properties" : {
| "message" : {
| "type" : "string"
| }
| },
| "required" : [
| "message"
| ]
| },
| "Payload" : {
| "type" : "object",
| "properties" : {
| "content" : {
| "type" : "string"
| }
| },
| "required" : [
| "content"
| ],
| "description" : "A simple payload"
| },
| "SimpleOutputBody" : {
| "type" : "object",
| "properties" : {
| "userName" : {
| "type" : "string"
| },
| "score" : {
| "type" : "integer",
| "format" : "int32"
| }
| },
| "required" : [
| "userName",
| "score"
| ]
| }
| }
| }
|}""".stripMargin
assertTrue(json == toJsonAst(expected))
},
test("alternative input") {
val generated = OpenAPIGen.fromEndpoints("Simple Endpoint", "1.0", alternativeInputEndpoint)
val json = toJsonAst(generated)
Expand Down
Loading

0 comments on commit ad6dac9

Please sign in to comment.