From 9bc006e09db3fac6a09a3957dca8a95acc012dc9 Mon Sep 17 00:00:00 2001 From: xGabrielDEV <58668092+xGabrielDEV@users.noreply.github.com> Date: Sun, 8 Nov 2020 11:10:14 -0300 Subject: [PATCH] Support guilds, provide more data to users & bug fixes --- .../gabriel/lunala/project/entity/Guild.kt | 23 +++++++++ .../com/gabriel/lunala/project/entity/User.kt | 33 +++++++++++-- .../lunala/project/service/GuildService.kt | 35 +++++++++++++ .../lunala/project/service/UserService.kt | 16 ++++-- .../com/gabriel/lunala/project/util/Client.kt | 15 ++---- .../gabriel/lunala/project/util/Premium.kt | 36 ++++++++++++++ src/jvmTest/kotlin/guilds.kt | 49 +++++++++++++++++++ src/jvmTest/kotlin/users.kt | 17 ++++--- 8 files changed, 197 insertions(+), 27 deletions(-) create mode 100644 src/commonMain/kotlin/com/gabriel/lunala/project/entity/Guild.kt create mode 100644 src/commonMain/kotlin/com/gabriel/lunala/project/service/GuildService.kt create mode 100644 src/commonMain/kotlin/com/gabriel/lunala/project/util/Premium.kt create mode 100644 src/jvmTest/kotlin/guilds.kt diff --git a/src/commonMain/kotlin/com/gabriel/lunala/project/entity/Guild.kt b/src/commonMain/kotlin/com/gabriel/lunala/project/entity/Guild.kt new file mode 100644 index 0000000..de3aa09 --- /dev/null +++ b/src/commonMain/kotlin/com/gabriel/lunala/project/entity/Guild.kt @@ -0,0 +1,23 @@ +package com.gabriel.lunala.project.entity + +import kotlinx.serialization.Serializable + +@Serializable +data class Guild( + val id: Long, + val locale: String, + val partner: Boolean +) + +@Serializable +data class GuildCreateDTO( + val id: Long, + val locale: String, + val partner: Boolean +) + +@Serializable +data class GuildUpdateDTO( + val locale: String? = null, + val partner: Boolean? = null +) \ No newline at end of file diff --git a/src/commonMain/kotlin/com/gabriel/lunala/project/entity/User.kt b/src/commonMain/kotlin/com/gabriel/lunala/project/entity/User.kt index 5cc3c0a..7f9660f 100644 --- a/src/commonMain/kotlin/com/gabriel/lunala/project/entity/User.kt +++ b/src/commonMain/kotlin/com/gabriel/lunala/project/entity/User.kt @@ -1,12 +1,39 @@ package com.gabriel.lunala.project.entity +import com.gabriel.lunala.project.util.PremiumType import kotlinx.serialization.Serializable @Serializable -data class User(val id: Long, val coins: Long, val planet: String) +data class User( + val id: Long, + val ship: Int, + val coins: Long, + val equipment: Int, + val crew: Int, + val planet: String, + val galaxy: String, + val premium: PremiumType +) @Serializable -data class UserCreateDTO(val id: Long, val coins: Long, val planet: String) +data class UserCreateDTO( + val id: Long, + val ship: Int, + val coins: Long, + val equipment: Int, + val crew: Int, + val planet: String, + val galaxy: String, + val premium: PremiumType +) @Serializable -data class UserUpdateDTO(val coins: Long?, val planet: String?) \ No newline at end of file +data class UserUpdateDTO( + val ship: Int? = null, + val coins: Long? = null, + val equipment: Int? = null, + val crew: Int? = null, + val planet: String? = null, + val galaxy: String? = null, + val premium: PremiumType? = null +) \ No newline at end of file diff --git a/src/commonMain/kotlin/com/gabriel/lunala/project/service/GuildService.kt b/src/commonMain/kotlin/com/gabriel/lunala/project/service/GuildService.kt new file mode 100644 index 0000000..013d9c0 --- /dev/null +++ b/src/commonMain/kotlin/com/gabriel/lunala/project/service/GuildService.kt @@ -0,0 +1,35 @@ +package com.gabriel.lunala.project.service + +import com.gabriel.lunala.project.LunalaWrapper +import com.gabriel.lunala.project.entity.Guild +import com.gabriel.lunala.project.entity.GuildCreateDTO +import com.gabriel.lunala.project.entity.GuildUpdateDTO +import io.ktor.client.request.* +import io.ktor.http.* + +class GuildService(private val wrapper: LunalaWrapper, private val route: String = "${wrapper.url}/guilds") { + + suspend fun create(create: GuildCreateDTO) = wrapper.client.post(route) { + header(HttpHeaders.Authorization, wrapper.key) + header("Content-Type", "application/json; charset=utf-8") + + body = create + } + + suspend fun retrieve(id: Long) = wrapper.client.get("$route/$id") { + header(HttpHeaders.Authorization, wrapper.key) + header("Content-Type", "application/json; charset=utf-8") + } + + suspend fun update(id: Long, update: GuildUpdateDTO): Guild = wrapper.client.put("$route/$id") { + header(HttpHeaders.Authorization, wrapper.key) + header("Content-Type", "application/json; charset=utf-8") + + body = update + } + + suspend fun delete(id: Long) = wrapper.client.delete("$route/$id") { + header(HttpHeaders.Authorization, wrapper.key) + header("Content-Type", "application/json; charset=utf-8") + } +} \ No newline at end of file diff --git a/src/commonMain/kotlin/com/gabriel/lunala/project/service/UserService.kt b/src/commonMain/kotlin/com/gabriel/lunala/project/service/UserService.kt index 0196ab0..f5c4f81 100644 --- a/src/commonMain/kotlin/com/gabriel/lunala/project/service/UserService.kt +++ b/src/commonMain/kotlin/com/gabriel/lunala/project/service/UserService.kt @@ -4,27 +4,33 @@ import com.gabriel.lunala.project.LunalaWrapper import com.gabriel.lunala.project.entity.User import com.gabriel.lunala.project.entity.UserCreateDTO import com.gabriel.lunala.project.entity.UserUpdateDTO -import com.gabriel.lunala.project.util.applyHeaders +import com.gabriel.lunala.project.util.Default import io.ktor.client.request.* import io.ktor.http.* class UserService(private val wrapper: LunalaWrapper, private val route: String = "${wrapper.url}/users") { suspend fun create(create: UserCreateDTO) = wrapper.client.post(route) { + header(HttpHeaders.Authorization, wrapper.key) + header(HttpHeaders.ContentType, ContentType.Application.Default) + body = create - applyHeaders(wrapper) } suspend fun retrieve(id: Long) = wrapper.client.get("$route/$id") { - applyHeaders(wrapper) + header(HttpHeaders.Authorization, wrapper.key) + header(HttpHeaders.ContentType, ContentType.Application.Default) } suspend fun update(id: Long, update: UserUpdateDTO): User = wrapper.client.put("$route/$id") { + header(HttpHeaders.Authorization, wrapper.key) + header(HttpHeaders.ContentType, ContentType.Application.Default) + body = update - applyHeaders(wrapper) } suspend fun delete(id: Long) = wrapper.client.delete("$route/$id") { - applyHeaders(wrapper) + header(HttpHeaders.Authorization, wrapper.key) + header(HttpHeaders.ContentType, ContentType.Application.Default) } } \ No newline at end of file diff --git a/src/commonMain/kotlin/com/gabriel/lunala/project/util/Client.kt b/src/commonMain/kotlin/com/gabriel/lunala/project/util/Client.kt index 4112a26..c2f741d 100644 --- a/src/commonMain/kotlin/com/gabriel/lunala/project/util/Client.kt +++ b/src/commonMain/kotlin/com/gabriel/lunala/project/util/Client.kt @@ -1,25 +1,18 @@ package com.gabriel.lunala.project.util -import com.gabriel.lunala.project.LunalaWrapper import io.ktor.client.* -import io.ktor.client.engine.* import io.ktor.client.features.json.* import io.ktor.client.features.json.serializer.* -import io.ktor.client.request.* -import io.ktor.client.utils.* import io.ktor.http.* import io.ktor.util.* +val ContentType.Application.Default + get() = "application/json; charset=utf-8" + @KtorExperimentalAPI -fun LunalaWrapper.prepareClient() = client.config { +fun HttpClientConfig<*>.prepareClient() = apply { install(JsonFeature) { serializer = KotlinxSerializer() acceptContentTypes = acceptContentTypes + ContentType("application", "json") } -}.let { this } - -// TODO: workaround -fun HttpRequestBuilder.applyHeaders(wrapper: LunalaWrapper) { - header(HttpHeaders.Authorization, wrapper.key) - header(HttpHeaders.ContentType, ContentType.Application.Json) } \ No newline at end of file diff --git a/src/commonMain/kotlin/com/gabriel/lunala/project/util/Premium.kt b/src/commonMain/kotlin/com/gabriel/lunala/project/util/Premium.kt new file mode 100644 index 0000000..d66c1fb --- /dev/null +++ b/src/commonMain/kotlin/com/gabriel/lunala/project/util/Premium.kt @@ -0,0 +1,36 @@ +package com.gabriel.lunala.project.util + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +@Serializable(with = PremiumSerializer::class) +enum class PremiumType(val id: Int) { + + NONE(0), + STAR(1), + SUPERNOVA(2), + BLACK_HOLE(3); + + companion object { + fun findById(id: Int): PremiumType? = values().firstOrNull { + it.id == id + } + } + +} + +class PremiumSerializer: KSerializer { + + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("premium_type", PrimitiveKind.INT) + + override fun deserialize(decoder: Decoder): PremiumType = + PremiumType.findById(decoder.decodeInt())!! + + override fun serialize(encoder: Encoder, value: PremiumType) = + encoder.encodeInt(value.ordinal) +} \ No newline at end of file diff --git a/src/jvmTest/kotlin/guilds.kt b/src/jvmTest/kotlin/guilds.kt new file mode 100644 index 0000000..c0222c0 --- /dev/null +++ b/src/jvmTest/kotlin/guilds.kt @@ -0,0 +1,49 @@ +import com.gabriel.lunala.project.LunalaWrapper +import com.gabriel.lunala.project.entity.Guild +import com.gabriel.lunala.project.entity.GuildCreateDTO +import com.gabriel.lunala.project.entity.GuildUpdateDTO +import com.gabriel.lunala.project.service.GuildService +import com.gabriel.lunala.project.util.prepareClient +import io.ktor.client.* +import io.ktor.client.engine.cio.* +import io.ktor.util.* +import org.junit.jupiter.api.Test + +class GuildOperationsTest { + + @Test + @KtorExperimentalAPI + suspend fun `test operations`() { + operate(GuildService(LunalaWrapper("http://localhost:8080/api", "key", client = HttpClient(CIO.create()) { + prepareClient() + }))) + } + +} + +private suspend fun operate(service: GuildService) { + create(service) { + println("Created $this") + } + update(service) { + println("Updated $this") + } + get(service) { + println("Got $this") + } + delete(service) { + println("Deleted $this") + } +} + +suspend fun create(service: GuildService, block: Guild.() -> Unit) = + service.create(GuildCreateDTO(1, "en-us", false)).also(block) + +suspend fun update(service: GuildService, block: Guild.() -> Unit) = + service.update(1, GuildUpdateDTO(locale = "pt-br")).also(block) + +suspend fun get(service: GuildService, block: Guild.() -> Unit) = + service.retrieve(1).also(block) + +suspend fun delete(service: GuildService, id: Long = 1, block: Long.() -> Unit) = + service.delete(id).also { block(id) } \ No newline at end of file diff --git a/src/jvmTest/kotlin/users.kt b/src/jvmTest/kotlin/users.kt index 63a4b4a..1de0dba 100644 --- a/src/jvmTest/kotlin/users.kt +++ b/src/jvmTest/kotlin/users.kt @@ -3,23 +3,26 @@ import com.gabriel.lunala.project.entity.User import com.gabriel.lunala.project.entity.UserCreateDTO import com.gabriel.lunala.project.entity.UserUpdateDTO import com.gabriel.lunala.project.service.UserService +import com.gabriel.lunala.project.util.PremiumType import com.gabriel.lunala.project.util.prepareClient import io.ktor.client.* import io.ktor.client.engine.cio.* import io.ktor.util.* import org.junit.jupiter.api.Test -class OperationsTest { +class UserOperationsTest { @Test @KtorExperimentalAPI suspend fun `test operations`() { - operate(UserService(LunalaWrapper("http://localhost:8080/api", "key", client = HttpClient(CIO.create())).prepareClient())) + operate(UserService(LunalaWrapper("http://localhost:8080/api", "key", client = HttpClient(CIO.create()) { + prepareClient() + }))) } } -suspend fun operate(service: UserService) { +private suspend fun operate(service: UserService) { create(service) { println("Created $this") } @@ -35,15 +38,13 @@ suspend fun operate(service: UserService) { } suspend fun create(service: UserService, block: User.() -> Unit) = - service.create(UserCreateDTO(1, 0, "Earth")).also(block) + service.create(UserCreateDTO(1, 0, 0, 0, 0, "Earth", "Milky Way", PremiumType.STAR)).also(block) suspend fun update(service: UserService, block: User.() -> Unit) = - service.update(1, UserUpdateDTO(20, null)).also(block) + service.update(1, UserUpdateDTO(coins = 20)).also(block) suspend fun get(service: UserService, block: User.() -> Unit) = service.retrieve(1).also(block) suspend fun delete(service: UserService, id: Long = 1, block: Long.() -> Unit) = - service.delete(id).also { block(id) } - -suspend fun main() = OperationsTest().`test operations`() \ No newline at end of file + service.delete(id).also { block(id) } \ No newline at end of file