one path actually works

This commit is contained in:
Ryan
2021-04-11 12:25:35 -04:00
parent 9c48d50394
commit 2918165361
15 changed files with 358 additions and 49 deletions

View File

@ -8,4 +8,5 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
testImplementation("org.jetbrains.kotlin:kotlin-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
testImplementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.12.0")
}

View File

@ -6,7 +6,7 @@ data class OpenApiSpecInfo(
val title: String,
val version: String,
val description: String?,
val termsOfService: URI?,
val contact: OpenApiSpecInfoContact?,
val license: OpenApiSpecInfoLicense?
val termsOfService: URI? = null,
val contact: OpenApiSpecInfoContact? = null,
val license: OpenApiSpecInfoLicense? = null
)

View File

@ -4,6 +4,6 @@ import java.net.URI
data class OpenApiSpecInfoContact(
val name: String,
val url: URI?,
val email: String? // TODO Enforce email
val url: URI? = null,
val email: String? = null // TODO Enforce email?
)

View File

@ -2,8 +2,8 @@ package org.leafygreens.kompendium.models
// TODO Oof -> https://swagger.io/specification/#media-type-object
data class OpenApiSpecMediaType(
val schema: String, // TODO sheesh -> https://swagger.io/specification/#schema-object needs to be referencable
val example: String, // TODO Enforce type? then serialize?
val examples: Map<String, String>, // needs to be mutually exclusive with example
val encoding: Map<String, String> // todo encoding object -> https://swagger.io/specification/#encoding-object
val schema: OpenApiSpecReferencable, // TODO sheesh -> https://swagger.io/specification/#schema-object needs to be referencable
val example: String? = null, // TODO Enforce type? then serialize?
val examples: Map<String, String>? = null, // needs to be mutually exclusive with example
val encoding: Map<String, String>? = null // todo encoding object -> https://swagger.io/specification/#encoding-object
)

View File

@ -1,17 +1,17 @@
package org.leafygreens.kompendium.models
data class OpenApiSpecPathItem(
val `$ref`: String?, // TODO Maybe drop this?
val summary: String?,
val description: String?,
val get: OpenApiSpecPathItemOperation?,
val put: OpenApiSpecPathItemOperation?,
val post: OpenApiSpecPathItemOperation?,
val delete: OpenApiSpecPathItemOperation?,
val options: OpenApiSpecPathItemOperation?,
val head: OpenApiSpecPathItemOperation?,
val patch: OpenApiSpecPathItemOperation?,
val trace: OpenApiSpecPathItemOperation?,
val servers: List<OpenApiSpecServer> = emptyList(),
val parameters: List<OpenApiSpecReferencable> = emptyList()
// val `$ref`: String?, // TODO need example of this... or just make whole thing referencable?
val summary: String? = null,
val description: String? = null,
val get: OpenApiSpecPathItemOperation? = null,
val put: OpenApiSpecPathItemOperation? = null,
val post: OpenApiSpecPathItemOperation? = null,
val delete: OpenApiSpecPathItemOperation? = null,
val options: OpenApiSpecPathItemOperation? = null,
val head: OpenApiSpecPathItemOperation? = null,
val patch: OpenApiSpecPathItemOperation? = null,
val trace: OpenApiSpecPathItemOperation? = null,
val servers: List<OpenApiSpecServer>? = null,
val parameters: List<OpenApiSpecReferencable>? = null
)

View File

@ -2,15 +2,16 @@ package org.leafygreens.kompendium.models
data class OpenApiSpecPathItemOperation(
val tags: Set<String> = emptySet(),
val summary: String?,
val description: String?,
val externalDocs: OpenApiSpecExternalDocumentation?,
val operationId: String?,
val parameters: List<OpenApiSpecReferencable> = emptyList(),
val requestBody: OpenApiSpecReferencable,
val responses: Map<String, OpenApiSpecReferencable>, // TODO How to enforce `default` requirement
val callbacks: Map<String, OpenApiSpecReferencable>,
val summary: String? = null,
val description: String? = null,
val externalDocs: OpenApiSpecExternalDocumentation? = null,
val operationId: String? = null,
val parameters: List<OpenApiSpecReferencable>? = null,
val requestBody: OpenApiSpecReferencable? = null,
val responses: Map<String, OpenApiSpecReferencable>? = null, // TODO How to enforce `default` requirement
val callbacks: Map<String, OpenApiSpecReferencable>? = null,
val deprecated: Boolean = false,
val security: Map<String, String>, // todo needs to reference objects in the security scheme 🤔
val servers: List<OpenApiSpecServer>
val security: List<Map<String, List<String>>>? = null, // todo big yikes... also needs to reference objects in the security scheme 🤔
val servers: List<OpenApiSpecServer>? = null,
val `x-codegen-request-body-name`: String? = null
)

View File

@ -9,10 +9,10 @@ data class OpenApiSpecCallback(
) : OpenApiSpecReferencable()
data class OpenApiSpecResponse(
val description: String,
val headers: Map<String, OpenApiSpecReferencable>,
val content: Map<String, OpenApiSpecMediaType>,
val links: Map<String, OpenApiSpecReferencable>
val description: String? = null,
val headers: Map<String, OpenApiSpecReferencable>? = null,
val content: Map<String, OpenApiSpecMediaType>? = null,
val links: Map<String, OpenApiSpecReferencable>? = null
) : OpenApiSpecReferencable()
data class OpenApiSpecHeader(
@ -29,3 +29,9 @@ data class OpenApiSpecParameter(
val deprecated: Boolean = false,
val allowEmptyValue: Boolean = false
) : OpenApiSpecReferencable()
data class OpenApiSpecRequest(
val description: String?,
val content: Map<String, OpenApiSpecMediaType>,
val required: Boolean = false
) : OpenApiSpecReferencable()

View File

@ -1,7 +0,0 @@
package org.leafygreens.kompendium.models
data class OpenApiSpecRequest(
val description: String?,
val content: Map<String, OpenApiSpecMediaType>,
val required: Boolean = false
)

View File

@ -1,7 +1,9 @@
package org.leafygreens.kompendium.models
import java.net.URI
data class OpenApiSpecServer(
val url: String,
val description: String?,
var variables: Map<String, OpenApiSpecServerVariable>?
val url: URI,
val description: String? = null,
var variables: Map<String, OpenApiSpecServerVariable>? = null
)

View File

@ -2,6 +2,6 @@ package org.leafygreens.kompendium.models
data class OpenApiSpecTag(
val name: String,
val description: String?,
val externalDocs: OpenApiSpecExternalDocumentation?
val description: String? = null,
val externalDocs: OpenApiSpecExternalDocumentation? = null
)

View File

@ -5,7 +5,6 @@ package kompendium
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class LibraryTest {
@Test fun testSomeLibraryMethod() {

View File

@ -0,0 +1,14 @@
package org.leafygreens.kompendium
import kotlin.test.Test
import kotlin.test.assertEquals
internal class KompendiumTest {
@Test
fun `Kompendium can be instantiated with no details`() {
val kompendium = Kompendium()
assertEquals(kompendium.spec.openapi, "3.0.3", "Kompendium has a default spec version of 3.0.3")
}
}

View File

@ -0,0 +1,27 @@
package org.leafygreens.kompendium.models
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import kotlin.test.Test
import kotlin.test.assertEquals
import org.leafygreens.kompendium.util.TestData
internal class OpenApiSpecTest {
private val mapper = jacksonObjectMapper()
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
.writerWithDefaultPrettyPrinter()
@Test
fun `OpenApiSpec can be serialized into a valid Open API Spec`() {
// when
val spec = TestData.testSpec
// do
val json = mapper.writeValueAsString(spec)
// expect
val expected = TestData.getFileSnapshot("petstore.json").trim()
assertEquals(expected, json, "Should serialize an empty spec")
}
}

View File

@ -0,0 +1,145 @@
package org.leafygreens.kompendium.util
import java.io.File
import java.net.URI
import org.leafygreens.kompendium.models.OpenApiSpec
import org.leafygreens.kompendium.models.OpenApiSpecExternalDocumentation
import org.leafygreens.kompendium.models.OpenApiSpecInfo
import org.leafygreens.kompendium.models.OpenApiSpecInfoContact
import org.leafygreens.kompendium.models.OpenApiSpecInfoLicense
import org.leafygreens.kompendium.models.OpenApiSpecMediaType
import org.leafygreens.kompendium.models.OpenApiSpecPathItem
import org.leafygreens.kompendium.models.OpenApiSpecPathItemOperation
import org.leafygreens.kompendium.models.OpenApiSpecReferenceObject
import org.leafygreens.kompendium.models.OpenApiSpecRequest
import org.leafygreens.kompendium.models.OpenApiSpecResponse
import org.leafygreens.kompendium.models.OpenApiSpecServer
import org.leafygreens.kompendium.models.OpenApiSpecTag
object TestData {
fun getFileSnapshot(fileName: String): String {
val snapshotPath = "src/test/resources"
val file = File("$snapshotPath/$fileName")
return file.readText()
}
val testSpec = OpenApiSpec(
info = OpenApiSpecInfo(
title = "Swagger Petstore",
description = "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
termsOfService = URI("http://swagger.io/terms/"),
contact = OpenApiSpecInfoContact(
name = "Team Swag",
email = "apiteam@swagger.io"
),
license = OpenApiSpecInfoLicense(
name = "Apache 2.0",
url = URI("http://www.apache.org/licenses/LICENSE-2.0.html")
),
version = "1.0.0"
),
externalDocs = OpenApiSpecExternalDocumentation(
description = "Find out more about Swagger",
url = URI("http://swagger.io")
),
servers = listOf(
OpenApiSpecServer(
url = URI("https://petstore.swagger.io/v2")
),
OpenApiSpecServer(
url = URI("http://petstore.swagger.io/v2")
)
),
tags = listOf(
OpenApiSpecTag(
name = "pet",
description = "Everything about your Pets",
externalDocs = OpenApiSpecExternalDocumentation(
description = "Find out more",
url = URI("http://swagger.io")
)
),
OpenApiSpecTag(
name = "store",
description = "Access to Petstore orders"
),
OpenApiSpecTag(
name = "user",
description = "Operations about user",
externalDocs = OpenApiSpecExternalDocumentation(
description = "Find out more about our store",
url = URI("http://swagger.io")
)
)
),
paths = mapOf(
"/pet" to OpenApiSpecPathItem(
put = OpenApiSpecPathItemOperation(
tags = setOf("pet"),
summary = "Update an existing pet",
operationId = "updatePet",
requestBody = OpenApiSpecRequest(
description = "Pet object that needs to be added to the store",
content = mapOf(
"application/json" to OpenApiSpecMediaType(
schema = OpenApiSpecReferenceObject(`$ref` = "#/components/schemas/Pet")
),
"application/xml" to OpenApiSpecMediaType(
schema = OpenApiSpecReferenceObject(`$ref` = "#/components/schemas/Pet")
)
),
required = true
),
responses = mapOf(
"400" to OpenApiSpecResponse(
description = "Invalid ID supplied",
content = emptyMap()
),
"404" to OpenApiSpecResponse(
description = "Pet not found",
content = emptyMap()
),
"405" to OpenApiSpecResponse(
description = "Validation exception",
content = emptyMap()
)
),
security = listOf(
mapOf(
"petstore_auth" to listOf("write:pets", "read:pets")
)
),
`x-codegen-request-body-name` = "body"
),
post = OpenApiSpecPathItemOperation(
tags = setOf("pet"),
summary = "Add a new pet to the store",
operationId = "addPet",
requestBody = OpenApiSpecRequest(
description = "Pet object that needs to be added to the store",
content = mapOf(
"application/json" to OpenApiSpecMediaType(
schema = OpenApiSpecReferenceObject(`$ref` = "#/components/schemas/Pet")
),
"application/xml" to OpenApiSpecMediaType(
schema = OpenApiSpecReferenceObject(`$ref` = "#/components/schemas/Pet")
)
)
),
responses = mapOf(
"405" to OpenApiSpecResponse(
description = "Invalid Input",
content = emptyMap()
)
),
security = listOf(
mapOf(
"petstore_auth" to listOf("write:pets", "read:pets")
)
),
`x-codegen-request-body-name` = "body"
)
)
)
)
}

View File

@ -0,0 +1,121 @@
{
"openapi" : "3.0.3",
"info" : {
"title" : "Swagger Petstore",
"version" : "1.0.0",
"description" : "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
"termsOfService" : "http://swagger.io/terms/",
"contact" : {
"name" : "Team Swag",
"email" : "apiteam@swagger.io"
},
"license" : {
"name" : "Apache 2.0",
"url" : "http://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"servers" : [ {
"url" : "https://petstore.swagger.io/v2"
}, {
"url" : "http://petstore.swagger.io/v2"
} ],
"paths" : {
"/pet" : {
"put" : {
"tags" : [ "pet" ],
"summary" : "Update an existing pet",
"operationId" : "updatePet",
"requestBody" : {
"description" : "Pet object that needs to be added to the store",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/Pet"
}
},
"application/xml" : {
"schema" : {
"$ref" : "#/components/schemas/Pet"
}
}
},
"required" : true
},
"responses" : {
"400" : {
"description" : "Invalid ID supplied",
"content" : { }
},
"404" : {
"description" : "Pet not found",
"content" : { }
},
"405" : {
"description" : "Validation exception",
"content" : { }
}
},
"deprecated" : false,
"security" : [ {
"petstore_auth" : [ "write:pets", "read:pets" ]
} ],
"x-codegen-request-body-name" : "body"
},
"post" : {
"tags" : [ "pet" ],
"summary" : "Add a new pet to the store",
"operationId" : "addPet",
"requestBody" : {
"description" : "Pet object that needs to be added to the store",
"content" : {
"application/json" : {
"schema" : {
"$ref" : "#/components/schemas/Pet"
}
},
"application/xml" : {
"schema" : {
"$ref" : "#/components/schemas/Pet"
}
}
},
"required" : false
},
"responses" : {
"405" : {
"description" : "Invalid Input",
"content" : { }
}
},
"deprecated" : false,
"security" : [ {
"petstore_auth" : [ "write:pets", "read:pets" ]
} ],
"x-codegen-request-body-name" : "body"
}
}
},
"security" : { },
"tags" : [ {
"name" : "pet",
"description" : "Everything about your Pets",
"externalDocs" : {
"url" : "http://swagger.io",
"description" : "Find out more"
}
}, {
"name" : "store",
"description" : "Access to Petstore orders"
}, {
"name" : "user",
"description" : "Operations about user",
"externalDocs" : {
"url" : "http://swagger.io",
"description" : "Find out more about our store"
}
} ],
"externalDocs" : {
"url" : "http://swagger.io",
"description" : "Find out more about Swagger"
}
}