mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-12-08 05:36:12 +00:00
Merge remote-tracking branch 'origin/4.1.x' into 5.0.x
This commit is contained in:
@@ -30,9 +30,8 @@ test {
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
||||
compile "com.squareup.moshi:moshi-kotlin:1.5.0"
|
||||
compile "com.squareup.moshi:moshi-adapters:1.5.0"
|
||||
compile "com.squareup.okhttp3:okhttp:3.14.0"
|
||||
compile "org.threeten:threetenbp:1.3.8"
|
||||
compile "com.squareup.moshi:moshi-kotlin:1.8.0"
|
||||
compile "com.squareup.moshi:moshi-adapters:1.8.0"
|
||||
compile "com.squareup.okhttp3:okhttp:3.14.2"
|
||||
testImplementation "io.kotlintest:kotlintest-runner-junit5:3.1.0"
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.ToJson
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.MediaType
|
||||
@@ -11,7 +8,6 @@ import okhttp3.HttpUrl
|
||||
import okhttp3.ResponseBody
|
||||
import okhttp3.Request
|
||||
import java.io.File
|
||||
import java.util.UUID
|
||||
|
||||
open class ApiClient(val baseUrl: String) {
|
||||
companion object {
|
||||
@@ -23,7 +19,7 @@ open class ApiClient(val baseUrl: String) {
|
||||
protected const val XmlMediaType = "application/xml"
|
||||
|
||||
@JvmStatic
|
||||
val client by lazy {
|
||||
val client: OkHttpClient by lazy {
|
||||
builder.build()
|
||||
}
|
||||
|
||||
@@ -37,13 +33,13 @@ open class ApiClient(val baseUrl: String) {
|
||||
MediaType.parse(mediaType), content
|
||||
)
|
||||
mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
|
||||
var builder = FormBody.Builder()
|
||||
// content's type *must* be Map<String, Any>
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(content as Map<String,String>).forEach { key, value ->
|
||||
builder = builder.add(key, value)
|
||||
}
|
||||
builder.build()
|
||||
FormBody.Builder().apply {
|
||||
// content's type *must* be Map<String, Any>
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(content as Map<String,String>).forEach { (key, value) ->
|
||||
add(key, value)
|
||||
}
|
||||
}.build()
|
||||
}
|
||||
mediaType == JsonMediaType -> RequestBody.create(
|
||||
MediaType.parse(mediaType), Serializer.moshi.adapter(T::class.java).toJson(content)
|
||||
@@ -58,18 +54,11 @@ open class ApiClient(val baseUrl: String) {
|
||||
return null
|
||||
}
|
||||
val bodyContent = body.string()
|
||||
if (bodyContent.length == 0) {
|
||||
if (bodyContent.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
return when(mediaType) {
|
||||
JsonMediaType -> Moshi.Builder().add(object {
|
||||
@ToJson
|
||||
fun toJson(uuid: UUID) = uuid.toString()
|
||||
@FromJson
|
||||
fun fromJson(s: String) = UUID.fromString(s)
|
||||
})
|
||||
.add(ByteArrayAdapter())
|
||||
.build().adapter(T::class.java).fromJson(bodyContent)
|
||||
JsonMediaType -> Serializer.moshi.adapter(T::class.java).fromJson(bodyContent)
|
||||
else -> TODO("responseBody currently only supports JSON body.")
|
||||
}
|
||||
}
|
||||
@@ -77,23 +66,22 @@ open class ApiClient(val baseUrl: String) {
|
||||
protected inline fun <reified T: Any?> request(requestConfig: RequestConfig, body : Any? = null): ApiInfrastructureResponse<T?> {
|
||||
val httpUrl = HttpUrl.parse(baseUrl) ?: throw IllegalStateException("baseUrl is invalid.")
|
||||
|
||||
var urlBuilder = httpUrl.newBuilder()
|
||||
.addPathSegments(requestConfig.path.trimStart('/'))
|
||||
|
||||
requestConfig.query.forEach { query ->
|
||||
query.value.forEach { queryValue ->
|
||||
urlBuilder = urlBuilder.addQueryParameter(query.key, queryValue)
|
||||
}
|
||||
}
|
||||
|
||||
val url = urlBuilder.build()
|
||||
val url = httpUrl.newBuilder()
|
||||
.addPathSegments(requestConfig.path.trimStart('/'))
|
||||
.apply {
|
||||
requestConfig.query.forEach { query ->
|
||||
query.value.forEach { queryValue ->
|
||||
addQueryParameter(query.key, queryValue)
|
||||
}
|
||||
}
|
||||
}.build()
|
||||
|
||||
// take content-type/accept from spec or set to default (application/json) if not defined
|
||||
if (requestConfig.headers[ContentType].isNullOrEmpty()) {
|
||||
requestConfig.headers.put(ContentType, JsonMediaType)
|
||||
requestConfig.headers[ContentType] = JsonMediaType
|
||||
}
|
||||
if (requestConfig.headers[Accept].isNullOrEmpty()) {
|
||||
requestConfig.headers.put(Accept, JsonMediaType)
|
||||
requestConfig.headers[Accept] = JsonMediaType
|
||||
}
|
||||
val headers = requestConfig.headers
|
||||
|
||||
@@ -108,7 +96,7 @@ open class ApiClient(val baseUrl: String) {
|
||||
// TODO: support multiple contentType options here.
|
||||
val contentType = (headers[ContentType] as String).substringBefore(";").toLowerCase()
|
||||
|
||||
var request : Request.Builder = when (requestConfig.method) {
|
||||
val request = when (requestConfig.method) {
|
||||
RequestMethod.DELETE -> Request.Builder().url(url).delete()
|
||||
RequestMethod.GET -> Request.Builder().url(url)
|
||||
RequestMethod.HEAD -> Request.Builder().url(url).head()
|
||||
@@ -116,12 +104,11 @@ open class ApiClient(val baseUrl: String) {
|
||||
RequestMethod.PUT -> Request.Builder().url(url).put(requestBody(body, contentType))
|
||||
RequestMethod.POST -> Request.Builder().url(url).post(requestBody(body, contentType))
|
||||
RequestMethod.OPTIONS -> Request.Builder().url(url).method("OPTIONS", null)
|
||||
}
|
||||
}.apply {
|
||||
headers.forEach { header -> addHeader(header.key, header.value) }
|
||||
}.build()
|
||||
|
||||
headers.forEach { header -> request = request.addHeader(header.key, header.value) }
|
||||
|
||||
val realRequest = request.build()
|
||||
val response = client.newCall(realRequest).execute()
|
||||
val response = client.newCall(request).execute()
|
||||
val accept = response.header(ContentType)?.substringBefore(";")?.toLowerCase()
|
||||
|
||||
// TODO: handle specific mapping types. e.g. Map<int, Class<?>>
|
||||
@@ -153,4 +140,4 @@ open class ApiClient(val baseUrl: String) {
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.ToJson
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class LocalDateAdapter {
|
||||
@ToJson
|
||||
fun toJson(value: LocalDate): String {
|
||||
return DateTimeFormatter.ISO_LOCAL_DATE.format(value)
|
||||
}
|
||||
|
||||
@FromJson
|
||||
fun fromJson(value: String): LocalDate {
|
||||
return LocalDate.parse(value, DateTimeFormatter.ISO_LOCAL_DATE)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.ToJson
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class LocalDateTimeAdapter {
|
||||
@ToJson
|
||||
fun toJson(value: LocalDateTime): String {
|
||||
return DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(value)
|
||||
}
|
||||
|
||||
@FromJson
|
||||
fun fromJson(value: String): LocalDateTime {
|
||||
return LocalDateTime.parse(value, DateTimeFormatter.ISO_LOCAL_DATE_TIME)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +1,18 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.KotlinJsonAdapterFactory
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Rfc3339DateJsonAdapter
|
||||
import java.util.*
|
||||
import com.squareup.moshi.adapters.Rfc3339DateJsonAdapter
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import java.util.Date
|
||||
|
||||
object Serializer {
|
||||
@JvmStatic
|
||||
val moshi: Moshi = Moshi.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.add(Date::class.java, Rfc3339DateJsonAdapter().nullSafe())
|
||||
.add(LocalDateTimeAdapter())
|
||||
.add(LocalDateAdapter())
|
||||
.add(UUIDAdapter())
|
||||
.add(ByteArrayAdapter())
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.openapitools.client.infrastructure
|
||||
|
||||
import com.squareup.moshi.FromJson
|
||||
import com.squareup.moshi.ToJson
|
||||
import java.util.UUID
|
||||
|
||||
class UUIDAdapter {
|
||||
@ToJson
|
||||
fun toJson(uuid: UUID) = uuid.toString()
|
||||
|
||||
@FromJson
|
||||
fun fromJson(s: String) = UUID.fromString(s)
|
||||
}
|
||||
@@ -2,8 +2,11 @@ package org.openapitools.client
|
||||
|
||||
import io.kotlintest.shouldBe
|
||||
import io.kotlintest.matchers.numerics.shouldBeGreaterThan
|
||||
import io.kotlintest.matchers.string.shouldContain
|
||||
import io.kotlintest.shouldThrow
|
||||
import io.kotlintest.specs.ShouldSpec
|
||||
import org.openapitools.client.apis.PetApi
|
||||
import org.openapitools.client.infrastructure.ClientException
|
||||
import org.openapitools.client.models.Category
|
||||
import org.openapitools.client.models.Pet
|
||||
import org.openapitools.client.models.Tag
|
||||
@@ -11,8 +14,11 @@ import org.openapitools.client.models.Tag
|
||||
class PetApiTest : ShouldSpec() {
|
||||
init {
|
||||
|
||||
val petId:Long = 10006
|
||||
val api = PetApi()
|
||||
|
||||
should("add a pet") {
|
||||
val petId:Long = 10006
|
||||
|
||||
val pet = Pet(
|
||||
id = petId,
|
||||
name = "kotlin client test",
|
||||
@@ -20,15 +26,11 @@ class PetApiTest : ShouldSpec() {
|
||||
category = Category(petId, "test kotlin category"),
|
||||
tags = arrayOf(Tag(petId, "test kotlin tag"))
|
||||
)
|
||||
|
||||
val api = PetApi()
|
||||
api.addPet(pet)
|
||||
|
||||
}
|
||||
|
||||
should("get pet by id") {
|
||||
val petId: Long = 10006
|
||||
val api = PetApi()
|
||||
val result = api.getPetById(petId)
|
||||
|
||||
result.id shouldBe (petId)
|
||||
@@ -42,7 +44,6 @@ class PetApiTest : ShouldSpec() {
|
||||
}
|
||||
|
||||
should("find pet by status") {
|
||||
val api = PetApi()
|
||||
val result = api.findPetsByStatus(arrayOf("available"))
|
||||
|
||||
result.size.shouldBeGreaterThan(0)
|
||||
@@ -58,15 +59,12 @@ class PetApiTest : ShouldSpec() {
|
||||
}
|
||||
|
||||
should("update a pet") {
|
||||
val petId:Long = 10007
|
||||
val pet = Pet(
|
||||
id = petId,
|
||||
name = "kotlin client updatePet",
|
||||
status = Pet.Status.pending,
|
||||
photoUrls = arrayOf("http://test_kotlin_unit_test.com")
|
||||
)
|
||||
|
||||
val api = PetApi()
|
||||
api.updatePet(pet)
|
||||
|
||||
// verify updated Pet
|
||||
@@ -77,14 +75,10 @@ class PetApiTest : ShouldSpec() {
|
||||
|
||||
}
|
||||
|
||||
//TODO the test fail cause client doesn't support other JSON contentType/Accept
|
||||
/*
|
||||
should("update a pet with form") {
|
||||
val petId:Long = 10007
|
||||
val name = "kotlin client updatePet with Form"
|
||||
val status = "pending"
|
||||
|
||||
val api = PetApi()
|
||||
api.updatePetWithForm(petId, name, status)
|
||||
|
||||
// verify updated Pet
|
||||
@@ -94,7 +88,16 @@ class PetApiTest : ShouldSpec() {
|
||||
result.status shouldBe (Pet.Status.pending)
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
should("delete a pet") {
|
||||
api.deletePet(petId, "apiKey")
|
||||
|
||||
// verify updated Pet
|
||||
val exception = shouldThrow<ClientException> {
|
||||
api.getPetById(petId)
|
||||
}
|
||||
exception.message?.shouldContain("Pet not found")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user