From 7c43569890f703c196523183153be3e9712375c9 Mon Sep 17 00:00:00 2001 From: ccornu <ccornu@takima.fr> Date: Fri, 7 Feb 2025 14:39:20 +0100 Subject: [PATCH] feat: first version of post new player endpoint --- src/main/kotlin/HelloService.kt | 5 ---- src/main/kotlin/player/Player.kt | 30 +++++++++++++++++++ src/main/kotlin/player/PlayerRepository.kt | 20 +++++++++++++ src/main/kotlin/player/PlayerRoute.kt | 20 +++++++++++++ src/main/kotlin/player/PlayerService.kt | 5 ++++ src/main/kotlin/player/PlayerServiceImpl.kt | 8 +++++ src/test/kotlin/ApplicationTest.kt | 21 ------------- .../kotlin/player/PlayerIntegrationTest.kt | 18 +++++++++++ src/test/kotlin/player/PlayerServiceTest.kt | 27 +++++++++++++++++ 9 files changed, 128 insertions(+), 26 deletions(-) delete mode 100644 src/main/kotlin/HelloService.kt create mode 100644 src/main/kotlin/player/Player.kt create mode 100644 src/main/kotlin/player/PlayerRepository.kt create mode 100644 src/main/kotlin/player/PlayerRoute.kt create mode 100644 src/main/kotlin/player/PlayerService.kt create mode 100644 src/main/kotlin/player/PlayerServiceImpl.kt delete mode 100644 src/test/kotlin/ApplicationTest.kt create mode 100644 src/test/kotlin/player/PlayerIntegrationTest.kt create mode 100644 src/test/kotlin/player/PlayerServiceTest.kt diff --git a/src/main/kotlin/HelloService.kt b/src/main/kotlin/HelloService.kt deleted file mode 100644 index b128e12..0000000 --- a/src/main/kotlin/HelloService.kt +++ /dev/null @@ -1,5 +0,0 @@ -package betclic.test - -fun interface HelloService { - fun sayHello() -} diff --git a/src/main/kotlin/player/Player.kt b/src/main/kotlin/player/Player.kt new file mode 100644 index 0000000..45d7d15 --- /dev/null +++ b/src/main/kotlin/player/Player.kt @@ -0,0 +1,30 @@ +package betclic.test.player + +import dev.andrewohara.dynamokt.DynamoKtPartitionKey +import kotlinx.serialization.Serializable + +@Serializable +data class Player( + val pseudo: String, + val pointsNumber: Int = 0, +) + +data class PlayerEntity( + @DynamoKtPartitionKey + val pseudo: String, + val pointsNumber: Int = 0, +) + +fun Player.toPlayerEntity(): PlayerEntity { + return PlayerEntity( + pseudo = pseudo, + pointsNumber = pointsNumber, + ) +} + +fun PlayerEntity.toPlayer(): Player { + return Player( + pseudo = pseudo, + pointsNumber = pointsNumber, + ) +} \ No newline at end of file diff --git a/src/main/kotlin/player/PlayerRepository.kt b/src/main/kotlin/player/PlayerRepository.kt new file mode 100644 index 0000000..68612ab --- /dev/null +++ b/src/main/kotlin/player/PlayerRepository.kt @@ -0,0 +1,20 @@ +package betclic.test.player + +import dev.andrewohara.dynamokt.DataClassTableSchema +import io.ktor.server.application.* +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.future.await +import org.slf4j.LoggerFactory +import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedAsyncClient + +class PlayerRepository(dynamoDbEnhancedClient: DynamoDbEnhancedAsyncClient) { + private val tableName = PlayerEntity::class.simpleName + private val tableSchema = DataClassTableSchema(PlayerEntity::class) + private val table = dynamoDbEnhancedClient.table(tableName, tableSchema) + private val logger = LoggerFactory.getLogger(Application::class.java) + + suspend fun createNewPlayer(player: Player): Unit = coroutineScope { + val saved = table.putItem(player.toPlayerEntity()).await() + logger.info("Successfully created new player $saved") + } +} \ No newline at end of file diff --git a/src/main/kotlin/player/PlayerRoute.kt b/src/main/kotlin/player/PlayerRoute.kt new file mode 100644 index 0000000..43d3ca7 --- /dev/null +++ b/src/main/kotlin/player/PlayerRoute.kt @@ -0,0 +1,20 @@ +package betclic.test.player + +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.request.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import org.koin.ktor.ext.inject + +fun Application.configureRouting() { + routing { + val playerService by inject<PlayerService>() + + post("/player") { + val request = call.receive<String>() + playerService.createNewPlayer(request) + call.respond(HttpStatusCode.Created) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/player/PlayerService.kt b/src/main/kotlin/player/PlayerService.kt new file mode 100644 index 0000000..222e09b --- /dev/null +++ b/src/main/kotlin/player/PlayerService.kt @@ -0,0 +1,5 @@ +package betclic.test.player + +interface PlayerService { + suspend fun createNewPlayer(pseudo: String) +} \ No newline at end of file diff --git a/src/main/kotlin/player/PlayerServiceImpl.kt b/src/main/kotlin/player/PlayerServiceImpl.kt new file mode 100644 index 0000000..6cfee70 --- /dev/null +++ b/src/main/kotlin/player/PlayerServiceImpl.kt @@ -0,0 +1,8 @@ +package betclic.test.player + +class PlayerServiceImpl(private val playerRepository: PlayerRepository) : PlayerService { + + override suspend fun createNewPlayer(pseudo: String) { + playerRepository.createNewPlayer(Player(pseudo = pseudo)) + } +} \ No newline at end of file diff --git a/src/test/kotlin/ApplicationTest.kt b/src/test/kotlin/ApplicationTest.kt deleted file mode 100644 index 3cd5bbc..0000000 --- a/src/test/kotlin/ApplicationTest.kt +++ /dev/null @@ -1,21 +0,0 @@ -package betclic.test - -import io.ktor.client.request.* -import io.ktor.http.* -import io.ktor.server.testing.* -import kotlin.test.Test -import kotlin.test.assertEquals - -class ApplicationTest { - - @Test - fun testRoot() = testApplication { - application { - module() - } - client.get("/").apply { - assertEquals(HttpStatusCode.OK, status) - } - } - -} diff --git a/src/test/kotlin/player/PlayerIntegrationTest.kt b/src/test/kotlin/player/PlayerIntegrationTest.kt new file mode 100644 index 0000000..dae72e7 --- /dev/null +++ b/src/test/kotlin/player/PlayerIntegrationTest.kt @@ -0,0 +1,18 @@ +package betclic.test.player + +import io.ktor.client.request.* +import io.ktor.http.* +import io.ktor.server.testing.* +import org.junit.Test +import kotlin.test.assertEquals + +class PlayerIntegrationTest { + @Test + fun `When calling post player, should return created`() = testApplication { + + assertEquals(HttpStatusCode.Created, client.post("/player") { + header(HttpHeaders.ContentType, ContentType.Text.Plain) + setBody("Test d'intégration") + }.status) + } +} \ No newline at end of file diff --git a/src/test/kotlin/player/PlayerServiceTest.kt b/src/test/kotlin/player/PlayerServiceTest.kt new file mode 100644 index 0000000..8d630f0 --- /dev/null +++ b/src/test/kotlin/player/PlayerServiceTest.kt @@ -0,0 +1,27 @@ +package betclic.test.player + +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.just +import io.mockk.mockk +import io.mockk.runs +import kotlinx.coroutines.runBlocking +import org.junit.Test + +class PlayerServiceTest { + + + private val playerRepository: PlayerRepository = mockk() + + private val playerService: PlayerServiceImpl = PlayerServiceImpl(playerRepository) + private val john = "John" + private val player1 = Player(pseudo = john) + + @Test + fun `should create a new player`() { + coEvery { playerRepository.createNewPlayer(player1) } just runs + runBlocking { playerService.createNewPlayer(john) } + coVerify(exactly = 1) { playerRepository.createNewPlayer(player1) } + } + +} \ No newline at end of file -- GitLab