Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LT-2] Optimizing the loot controller #43

Merged
merged 2 commits into from
Jan 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/kotlin/fr/bfr/api/CharacterRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package fr.bfr.api

import fr.bfr.model.Character
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Service
import org.springframework.stereotype.Repository

@Service
@Repository
interface CharacterRepository : JpaRepository<Character, Long> {
override fun findAll(): List<Character>
}
6 changes: 2 additions & 4 deletions src/main/kotlin/fr/bfr/api/DropRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package fr.bfr.api

import fr.bfr.model.DropChance
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.lang.NonNull
import org.springframework.stereotype.Service
import org.springframework.stereotype.Repository

@Service
@Repository
interface DropChanceRepository : JpaRepository<DropChance, Int> {
@NonNull
override fun findAll(): List<DropChance>
}
3 changes: 1 addition & 2 deletions src/main/kotlin/fr/bfr/api/LootApi.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package fr.bfr.api

import fr.bfr.model.Character
import fr.bfr.model.DropChance

interface LootApi {
fun pull(data: List<Character>, dropChances: List<DropChance>, numberOfPull: Int): List<Character>
fun pull(numberOfPull: Int): List<Character>
}
15 changes: 3 additions & 12 deletions src/main/kotlin/fr/bfr/controller/LootController.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package fr.bfr.controller

import fr.bfr.api.CharacterRepository
import fr.bfr.api.DropChanceRepository
import fr.bfr.model.Character
import fr.bfr.services.LootService
import org.slf4j.LoggerFactory
Expand All @@ -14,21 +12,14 @@ import org.springframework.web.bind.annotation.RestController

@RestController
class LootController @Autowired constructor(
val characterRepository: CharacterRepository,
val dropRepository: DropChanceRepository,
val lootService: LootService
) {
@GetMapping(value = ["/pull"], produces = [MediaType.APPLICATION_JSON_VALUE])
fun pull(): ResponseEntity<List<Character>> {
logger.info("/pull endpoint was called !")
val characters = characterRepository.findAll()
val dropChances = dropRepository.findAll()
var lootedCharacters: List<Character> = ArrayList()
if (characters.isNotEmpty() && dropChances.isNotEmpty()) {
logger.info("Retrieving all looted characters...")
lootedCharacters = lootService.pull(characters, dropChances, 10)
logger.info("Characters looted successfully !")
}
logger.info("Retrieving all looted characters...")
val lootedCharacters: List<Character> = lootService.pull(10)

return ResponseEntity(lootedCharacters, HttpStatus.OK)
}

Expand Down
4 changes: 1 addition & 3 deletions src/main/kotlin/fr/bfr/model/Character.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package fr.bfr.model

import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.persistence.Table

@Entity
@Table(name = "t_character")
class Character(
@Id
@GeneratedValue
var id: Long,
var name: String,
var rarity: Int
var rarity: Int,
)
2 changes: 1 addition & 1 deletion src/main/kotlin/fr/bfr/model/DropChance.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ import javax.persistence.Table
class DropChance(
@Id
var rarity: Int,
var chance: Double
var chance: Int,
)
15 changes: 10 additions & 5 deletions src/main/kotlin/fr/bfr/services/LootService.kt
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
package fr.bfr.services

import fr.bfr.api.CharacterRepository
import fr.bfr.api.DropChanceRepository
import fr.bfr.api.LootApi
import fr.bfr.model.Character
import fr.bfr.model.DropChance
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.security.SecureRandom

@Service
class LootService : LootApi {
class LootService @Autowired constructor(
val characterRepository: CharacterRepository,
val dropChanceRepository: DropChanceRepository
) : LootApi {
val secureRandom: SecureRandom = SecureRandom()

override fun pull(
data: List<Character>,
dropChances: List<DropChance>,
numberOfPull: Int
): List<Character> {
val data: List<Character> = characterRepository.findAll();
val dropChanceList: List<DropChance> = dropChanceRepository.findAll();
val pulledCharacters: MutableList<Character> = ArrayList()
val charactersListWithDropChance: MutableList<Character> = ArrayList()
var counter = 0

// Setting an array of 100 characters with number of each character matching the chance
for (dropChance in dropChances) {
for (dropChance in dropChanceList) {
while (counter < dropChance.chance) {
charactersListWithDropChance.add(data[dropChance.rarity - 1])
counter++
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/db/scripts/init-database.sql
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
CREATE TABLE public.t_character (
id int8 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
id int8 NOT NULL,
"name" varchar(255) NULL,
rarity int4 NULL,
CONSTRAINT t_character_pkey PRIMARY KEY (id)
);

CREATE TABLE public.t_drop (
rarity int4 NOT NULL,
chance float8 NULL,
chance int4 NULL,
CONSTRAINT t_drop_pkey PRIMARY KEY (rarity)
);
37 changes: 21 additions & 16 deletions src/test/kotlin/controller/LootControllerTest.kt
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
package controller

import fr.bfr.Main
import fr.bfr.controller.LootController
import fr.bfr.model.Character
import org.assertj.core.api.Assertions
import fr.bfr.services.LootService
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.web.client.TestRestTemplate
import org.springframework.boot.test.web.client.getForEntity
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import org.springframework.http.HttpStatus
import org.springframework.test.context.ActiveProfiles
import org.springframework.http.ResponseEntity

@SpringBootTest(classes = [Main::class], webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
class LootControllerTest(
@Autowired val restTemplate: TestRestTemplate
) {
class LootControllerTest {

@Test
fun `Integration test of the Pull endpoint`() {
val entity = restTemplate.getForEntity<List<Character>>("/pull")
Assertions.assertThat(entity.statusCode).isEqualTo(HttpStatus.OK)
Assertions.assertThat(entity.body).isEqualTo(emptyList<Character>())
fun `Check if pull endpoint is sending correct data`() {
// Mocking
val mockLootService: LootService = mock()
whenever(mockLootService.pull(any())).thenReturn(listOf(Character(1, "bfr", 1)))
val lootController = LootController(mockLootService)

// Using the method to test
val result: ResponseEntity<List<Character>> = lootController.pull()

// Assertions
Assertions.assertEquals(HttpStatus.OK, result.statusCode)
result.body?.let { Assertions.assertEquals(1, it.size) }
Assertions.assertEquals(true, result.body?.isNotEmpty() ?: false)
}
}
37 changes: 16 additions & 21 deletions src/test/kotlin/services/LootServiceTest.kt
Original file line number Diff line number Diff line change
@@ -1,40 +1,35 @@
package services

import fr.bfr.Main
import fr.bfr.api.CharacterRepository
import fr.bfr.api.DropChanceRepository
import fr.bfr.model.Character
import fr.bfr.model.DropChance
import fr.bfr.services.LootService
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.ActiveProfiles
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import fr.bfr.model.Character as CharacterBfr

@SpringBootTest(classes = [Main::class])
@ActiveProfiles("test")
class LootServiceTest(@Autowired val lootService: LootService) {
class LootServiceTest {

@Test
fun `Assert pull method is working`() {
//data
val data: List<CharacterBfr> = generateCharacterList()
//DropChance
val dropChance: List<DropChance> = generateDropChanceList()
//NumberOfPull
// Mocking
val mockCharacterRepository: CharacterRepository = mock()
val mockDropChanceRepository: DropChanceRepository = mock()
whenever(mockCharacterRepository.findAll()).thenReturn(listOf(Character(1, "bfr", 1)))
whenever(mockDropChanceRepository.findAll()).thenReturn(listOf(DropChance(1, 100)))
val lootService = LootService(mockCharacterRepository, mockDropChanceRepository)

// NumberOfPull
val numberOfPull = 1
val result: List<CharacterBfr> = lootService.pull(data, dropChance, numberOfPull)
val result: List<CharacterBfr> = lootService.pull(numberOfPull)

// Assertions
Assertions.assertEquals(result.size, 1)
Assertions.assertEquals(result[0].id, 1)
Assertions.assertEquals(result[0].name, "bfr")
Assertions.assertEquals(result[0].rarity, 1)
}

fun generateCharacterList(): List<CharacterBfr> {
return listOf(Character(1, "bfr", 1))
}

fun generateDropChanceList(): List<DropChance> {
return listOf(DropChance(1, 100.0))
}
}