diff --git a/src/main/kotlin/HelloService.kt b/src/main/kotlin/HelloService.kt deleted file mode 100644 index b128e1231c8ca80a3e568c671f2252949be50d1a..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..45d7d159598df91a96cdec2fafc381fa834ee109 --- /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 0000000000000000000000000000000000000000..68612abc1f05c13856e44dec0592e392df1675f3 --- /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 0000000000000000000000000000000000000000..43d3ca7de521af6cfbb1b14fda5641d58034a970 --- /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 0000000000000000000000000000000000000000..222e09bc7bdbb3038cbcc0112a682a17163ad676 --- /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 0000000000000000000000000000000000000000..6cfee70fd1ad27f9b17d231673f00d85beeee3e4 --- /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 3cd5bbc9b1a67067915686c55d9750a49607eee4..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..dae72e74c1a77871b05490528c4b7c798d0d5a1a --- /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 0000000000000000000000000000000000000000..8d630f0fffb42a72a5f2fdeb529df5f9b8cb58b5 --- /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