diff --git a/build.gradle b/build.gradle index aafae20..30960ba 100644 --- a/build.gradle +++ b/build.gradle @@ -13,17 +13,66 @@ repositories { } test { + // listen to events in the test execution lifecycle + beforeTest { descriptor -> + logger.lifecycle("Running test: " + descriptor) + } + + onOutput { descriptor, event -> + logger.lifecycle("Test: " + descriptor + " produced standard out/err: " + event.message ) + } + useJUnitPlatform() - finalizedBy jacocoTestReport +} + +def jacocoExcludes = [ + 'io/github/marcusadriano/brawlstars/model/**' +] + +def jacocoRulesExcludes = [ + 'io.github.marcusadriano.brawlstars.model.**' +] + +jacocoTestCoverageVerification { + violationRules { + rule { + element = 'METHOD' + excludes = jacocoRulesExcludes + limit { + counter = 'BRANCH' + minimum = 0.9 + } + } + } } jacocoTestReport { - dependsOn test reports { xml.enabled true + csv.enabled false + html.enabled true + } + afterEvaluate { + classDirectories.setFrom(files(classDirectories.files.collect { + fileTree(dir: it, exclude: jacocoExcludes) + })) } } +check { + dependsOn jacocoTestCoverageVerification + dependsOn jacocoTestReport +} + +compileKotlin { + kotlinOptions.jvmTarget = "1.8" + kotlinOptions { + freeCompilerArgs = ["-Xinline-classes", "-Xjvm-default=compatibility"] + } +} +compileTestKotlin { + kotlinOptions.jvmTarget = "1.8" +} dependencies { implementation 'com.squareup.retrofit2:converter-gson:2.9.0' @@ -32,17 +81,8 @@ dependencies { implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7' + testImplementation 'com.squareup.retrofit2:retrofit-mock:2.9.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.0' testImplementation group: 'org.mockito', name: 'mockito-all', version: '1.10.19' -} - -compileKotlin { - kotlinOptions.jvmTarget = "1.8" - kotlinOptions { - freeCompilerArgs = ["-Xinline-classes", "-Xjvm-default=compatibility"] - } -} -compileTestKotlin { - kotlinOptions.jvmTarget = "1.8" } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 8ff1f99..ca5d238 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ -rootProject.name = 'BrawlStarsSDK' +rootProject.name = 'BrawlStars-SDK' diff --git a/src/main/java/examples/MainJavaExample.java b/src/main/java/examples/MainJavaExample.java deleted file mode 100644 index bf610a2..0000000 --- a/src/main/java/examples/MainJavaExample.java +++ /dev/null @@ -1,30 +0,0 @@ -package examples; - -import io.github.marcusadriano.brawlstars.BrawlStars; -import io.github.marcusadriano.brawlstars.model.Player; -import io.github.marcusadriano.brawlstars.model.Result; -import io.github.marcusadriano.brawlstars.service.BrawlStarsService; - -import java.util.function.Function; - -public class MainJavaExample { - - private static final Function, String> printResult = result -> { - if (result instanceof Result.Success) { - Result.Success player = (Result.Success) result; - return player.getData().getName() + " | trophies = " + player.getData().getTrophies(); - } - - Result.Error error = (Result.Error) result; - return "Result.Error: " + error.getData().getReason(); - }; - - public static void main(String[] args) { - BrawlStars.setup(args[0]); - BrawlStarsService service = BrawlStars.service(); - Result result = service.player("#9UV9UG9J"); - - System.out.println(printResult.apply(result)); - } -} - diff --git a/src/main/java/examples/MainKotlinExample.kt b/src/main/java/examples/MainKotlinExample.kt deleted file mode 100644 index 664de4a..0000000 --- a/src/main/java/examples/MainKotlinExample.kt +++ /dev/null @@ -1,60 +0,0 @@ -package examples - -import io.github.marcusadriano.brawlstars.BrawlStars -import io.github.marcusadriano.brawlstars.model.Battle -import io.github.marcusadriano.brawlstars.model.BattleLog -import io.github.marcusadriano.brawlstars.model.Player -import io.github.marcusadriano.brawlstars.model.Result - -fun countBattleResult(battle: Battle, counter: Int): Int { - var value = counter - if (battle.type != "ranked") { - return counter - } - if (battle.result != null) { - when (battle.result) { - "victory" -> value++ - } - } - - if (battle.rank != null) { - when (battle.rank) { - 1, 2 -> value++ - } - } - - return value -} - -fun printResult(result: Result) { - when(result) { - is Result.Success -> { - val battleLog = result.data - var totalTrophies = 0 - var totalVictories = 0 - val totalBattles = battleLog.items!!.size - - battleLog.items.forEach { - val battle: Battle = it.battle as Battle - if (battle.trophyChange != null) { - totalTrophies += battle.trophyChange - } - totalVictories = countBattleResult(battle, totalVictories) - } - val percent = totalVictories.toDouble()/totalBattles * 100 - println("You won $percent% of $totalBattles battles. Sum total of $totalTrophies trophies") - } - is Result.Error -> { - println("Error ==> ${result.data.reason}") - } - } -} - -fun main(args: Array) { - val token = args[0] - BrawlStars.setup(token) - val service = BrawlStars.service() - val result: Result = service.battleLog("#9UV9UG9J") - printResult(result) -} - diff --git a/src/main/kotlin/io/github/marcusadriano/brawlstars/BrawlStars.kt b/src/main/kotlin/io/github/marcusadriano/brawlstars/BrawlStars.kt index 49d76d9..cdac22c 100644 --- a/src/main/kotlin/io/github/marcusadriano/brawlstars/BrawlStars.kt +++ b/src/main/kotlin/io/github/marcusadriano/brawlstars/BrawlStars.kt @@ -1,15 +1,35 @@ package io.github.marcusadriano.brawlstars +import io.github.marcusadriano.brawlstars.model.BrawlStarsAuthInterceptor +import io.github.marcusadriano.brawlstars.model.BrawlStarsToken import io.github.marcusadriano.brawlstars.service.BrawlStarsService +import io.github.marcusadriano.brawlstars.service.BrawlStarsServiceApi import io.github.marcusadriano.brawlstars.service.impl.BrawlStarsServiceImpl -import java.lang.RuntimeException +import okhttp3.OkHttpClient +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory object BrawlStars { private var service: BrawlStarsService? = null @JvmStatic fun setup(token: String) { - service = BrawlStarsServiceImpl(BrawlStarsToken(token)) + val bsToken = BrawlStarsToken(token) + + val tokenInterceptor = + BrawlStarsAuthInterceptor(bsToken) + + val okHttpClient = OkHttpClient.Builder() + .addInterceptor(tokenInterceptor) + .build() + + val retrofit = Retrofit.Builder() + .client(okHttpClient) + .baseUrl("https://api.brawlstars.com/v1/") + .addConverterFactory(GsonConverterFactory.create()) + .build() + val api = retrofit.create(BrawlStarsServiceApi::class.java) + service = BrawlStarsServiceImpl(api) } @JvmStatic fun service(): BrawlStarsService { diff --git a/src/main/kotlin/io/github/marcusadriano/brawlstars/BrawlStarsAuthInterceptor.kt b/src/main/kotlin/io/github/marcusadriano/brawlstars/model/BrawlStarsAuthInterceptor.kt similarity index 92% rename from src/main/kotlin/io/github/marcusadriano/brawlstars/BrawlStarsAuthInterceptor.kt rename to src/main/kotlin/io/github/marcusadriano/brawlstars/model/BrawlStarsAuthInterceptor.kt index 57d034b..6f6bd55 100644 --- a/src/main/kotlin/io/github/marcusadriano/brawlstars/BrawlStarsAuthInterceptor.kt +++ b/src/main/kotlin/io/github/marcusadriano/brawlstars/model/BrawlStarsAuthInterceptor.kt @@ -1,4 +1,4 @@ -package io.github.marcusadriano.brawlstars +package io.github.marcusadriano.brawlstars.model import okhttp3.Interceptor import okhttp3.Request @@ -10,7 +10,6 @@ internal class BrawlStarsAuthInterceptor(val token: BrawlStarsToken) : Intercept const val AUTHORIZATION = "Authorization" } - override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() diff --git a/src/main/kotlin/io/github/marcusadriano/brawlstars/BrawlStarsToken.kt b/src/main/kotlin/io/github/marcusadriano/brawlstars/model/BrawlStarsToken.kt similarity index 69% rename from src/main/kotlin/io/github/marcusadriano/brawlstars/BrawlStarsToken.kt rename to src/main/kotlin/io/github/marcusadriano/brawlstars/model/BrawlStarsToken.kt index 820ca33..056bba2 100644 --- a/src/main/kotlin/io/github/marcusadriano/brawlstars/BrawlStarsToken.kt +++ b/src/main/kotlin/io/github/marcusadriano/brawlstars/model/BrawlStarsToken.kt @@ -1,4 +1,4 @@ -package io.github.marcusadriano.brawlstars +package io.github.marcusadriano.brawlstars.model inline class BrawlStarsToken(private val value: String) { diff --git a/src/main/kotlin/io/github/marcusadriano/brawlstars/service/impl/BrawlStarsServiceImpl.kt b/src/main/kotlin/io/github/marcusadriano/brawlstars/service/impl/BrawlStarsServiceImpl.kt index 67a7d13..62d2d21 100644 --- a/src/main/kotlin/io/github/marcusadriano/brawlstars/service/impl/BrawlStarsServiceImpl.kt +++ b/src/main/kotlin/io/github/marcusadriano/brawlstars/service/impl/BrawlStarsServiceImpl.kt @@ -1,38 +1,15 @@ package io.github.marcusadriano.brawlstars.service.impl import com.google.gson.Gson -import io.github.marcusadriano.brawlstars.BrawlStarsAuthInterceptor -import io.github.marcusadriano.brawlstars.BrawlStarsToken import io.github.marcusadriano.brawlstars.model.BattleLog import io.github.marcusadriano.brawlstars.model.Error import io.github.marcusadriano.brawlstars.model.Player import io.github.marcusadriano.brawlstars.model.Result import io.github.marcusadriano.brawlstars.service.BrawlStarsService import io.github.marcusadriano.brawlstars.service.BrawlStarsServiceApi -import okhttp3.OkHttpClient import retrofit2.Response -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory -internal class BrawlStarsServiceImpl(token: BrawlStarsToken) : BrawlStarsService { - - private val retrofit: Retrofit - private val api: BrawlStarsServiceApi - - init { - val tokenInterceptor = BrawlStarsAuthInterceptor(token) - - val okHttpClient = OkHttpClient.Builder() - .addInterceptor(tokenInterceptor) - .build() - - retrofit = Retrofit.Builder() - .client(okHttpClient) - .baseUrl("https://api.brawlstars.com/v1/") - .addConverterFactory(GsonConverterFactory.create()) - .build() - api = retrofit.create(BrawlStarsServiceApi::class.java) - } +internal class BrawlStarsServiceImpl(private val api: BrawlStarsServiceApi) : BrawlStarsService { protected fun parseResult(response: Response): Result { if (response.isSuccessful) { diff --git a/src/test/kotlin/io/github/marcusadriano/brawlstars/BrawlStarsTest.kt b/src/test/kotlin/io/github/marcusadriano/brawlstars/BrawlStarsTest.kt new file mode 100644 index 0000000..cb65ee5 --- /dev/null +++ b/src/test/kotlin/io/github/marcusadriano/brawlstars/BrawlStarsTest.kt @@ -0,0 +1,22 @@ +package io.github.marcusadriano.brawlstars + +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +internal class BrawlStarsTest { + + @Test + fun `should create BsService Instance`() { + BrawlStars.setup("any") + val bs = BrawlStars.service() + assertNotNull(bs) + } + + @Test + fun `should throw RuntimeException`() { + assertThrows { + BrawlStars.service() + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/io/github/marcusadriano/brawlstars/service/impl/BrawlStarsServiceImplTest.kt b/src/test/kotlin/io/github/marcusadriano/brawlstars/service/impl/BrawlStarsServiceImplTest.kt index 60bb68e..869e7af 100644 --- a/src/test/kotlin/io/github/marcusadriano/brawlstars/service/impl/BrawlStarsServiceImplTest.kt +++ b/src/test/kotlin/io/github/marcusadriano/brawlstars/service/impl/BrawlStarsServiceImplTest.kt @@ -1,15 +1,100 @@ package io.github.marcusadriano.brawlstars.service.impl -import org.junit.jupiter.api.Assertions.* +import com.google.gson.Gson +import io.github.marcusadriano.brawlstars.model.BattleLog +import io.github.marcusadriano.brawlstars.model.Error +import io.github.marcusadriano.brawlstars.model.Player +import io.github.marcusadriano.brawlstars.model.Result +import io.github.marcusadriano.brawlstars.service.BrawlStarsService +import io.github.marcusadriano.brawlstars.service.BrawlStarsServiceApi +import io.github.marcusadriano.brawlstars.utils.PlayerHttpMockResponses +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.Mockito.`when` +import org.mockito.Mockito.anyString +import org.mockito.MockitoAnnotations +import retrofit2.mock.Calls internal class BrawlStarsServiceImplTest { + @Mock + private lateinit var bsapi: BrawlStarsServiceApi + private lateinit var service: BrawlStarsService + + @BeforeEach + fun setUp() { + MockitoAnnotations.initMocks(this) + this.service = BrawlStarsServiceImpl(bsapi) + + `when`(bsapi.player(anyString())).thenReturn(Calls.response(PlayerHttpMockResponses.player())) + `when`(bsapi.battleLog(anyString())).thenReturn(Calls.response(PlayerHttpMockResponses.battleLog())) + } + @Test - fun player() { + fun `should get Player Info`() { + val result: Result = service.player("#test") + assertTrue(result is Result.Success) + when(result) { + is Result.Success -> { + val player = result.data + val expectedPlayer = PlayerHttpMockResponses.player().body()!! + + assertEquals(expectedPlayer.name, player.name) + assertEquals(expectedPlayer.trophies, player.trophies) + } + else -> error("result != player ==> $result") + } + + } + + @Test + fun `should get Error on Player request`() { + Mockito.reset(bsapi) + `when`(bsapi.player(anyString())).thenReturn(Calls.response(PlayerHttpMockResponses.notFound())) + val result: Result = service.player("#test") + assertTrue(result is Result.Error) + when (result) { + is Result.Error -> { + val error = result.data + val expectedPlayer = Gson().fromJson(PlayerHttpMockResponses.RESPONSE_NOT_FOUND, Error::class.java) + assertEquals(expectedPlayer.reason, error.reason) + } + else -> error("result != error ==> $result") + } + } + + @Test + fun `should get BattleLog info`() { + val result: Result = service.battleLog("#test") + assertTrue(result is Result.Success) + when(result) { + is Result.Success -> { + val battleLog = result.data + val expectedPlayer = PlayerHttpMockResponses.battleLog().body()!! + + assertEquals(expectedPlayer.items!!.size, battleLog.items!!.size) + } + else -> error("result != player ==> $result") + } } @Test - fun battleLog() { + fun `should get Error on BattleLog request`() { + Mockito.reset(bsapi) + `when`(bsapi.battleLog(anyString())).thenReturn(Calls.response(PlayerHttpMockResponses.notFound())) + val result: Result = service.battleLog("#test") + assertTrue(result is Result.Error) + when (result) { + is Result.Error -> { + val error = result.data + val expectedPlayer = Gson().fromJson(PlayerHttpMockResponses.RESPONSE_NOT_FOUND, Error::class.java) + assertEquals(expectedPlayer.reason, error.reason) + } + else -> error("result != error ==> $result") + } } } \ No newline at end of file diff --git a/src/test/kotlin/io/github/marcusadriano/brawlstars/utils/PlayerHttpMockResponses.kt b/src/test/kotlin/io/github/marcusadriano/brawlstars/utils/PlayerHttpMockResponses.kt new file mode 100644 index 0000000..d4625c3 --- /dev/null +++ b/src/test/kotlin/io/github/marcusadriano/brawlstars/utils/PlayerHttpMockResponses.kt @@ -0,0 +1,36 @@ +package io.github.marcusadriano.brawlstars.utils + +import com.google.gson.Gson +import io.github.marcusadriano.brawlstars.model.BattleLog +import io.github.marcusadriano.brawlstars.model.Player +import okhttp3.MediaType +import okhttp3.ResponseBody +import retrofit2.Response + +object PlayerHttpMockResponses { + + const val PLAYER_RESPONSE_OK: String = "{ \"tag\": \"#V2GP99J8\", \"name\": \"JOSEFA\", \"nameColor\": \"0xffff8afb\", \"icon\": { \"id\": 28000000 }, \"trophies\": 570, \"highestTrophies\": 570, \"expLevel\": 13, \"expPoints\": 1262, \"isQualifiedFromChampionshipChallenge\": false, \"3vs3Victories\": 49, \"soloVictories\": 2, \"duoVictories\": 30, \"bestRoboRumbleTime\": 0, \"bestTimeAsBigBrawler\": 0, \"club\": {}, \"brawlers\": [ { \"id\": 16000000, \"name\": \"SHELLY\", \"power\": 5, \"rank\": 13, \"trophies\": 238, \"highestTrophies\": 238, \"starPowers\": [], \"gadgets\": [] }, { \"id\": 16000001, \"name\": \"COLT\", \"power\": 4, \"rank\": 7, \"trophies\": 81, \"highestTrophies\": 81, \"starPowers\": [], \"gadgets\": [] }, { \"id\": 16000002, \"name\": \"BULL\", \"power\": 2, \"rank\": 4, \"trophies\": 38, \"highestTrophies\": 38, \"starPowers\": [], \"gadgets\": [] }, { \"id\": 16000006, \"name\": \"BARLEY\", \"power\": 4, \"rank\": 4, \"trophies\": 36, \"highestTrophies\": 36, \"starPowers\": [], \"gadgets\": [] }, { \"id\": 16000007, \"name\": \"JESSIE\", \"power\": 1, \"rank\": 1, \"trophies\": 0, \"highestTrophies\": 0, \"starPowers\": [], \"gadgets\": [] }, { \"id\": 16000008, \"name\": \"NITA\", \"power\": 5, \"rank\": 5, \"trophies\": 47, \"highestTrophies\": 47, \"starPowers\": [], \"gadgets\": [] }, { \"id\": 16000013, \"name\": \"POCO\", \"power\": 3, \"rank\": 8, \"trophies\": 112, \"highestTrophies\": 114, \"starPowers\": [], \"gadgets\": [] }, { \"id\": 16000018, \"name\": \"DARRYL\", \"power\": 1, \"rank\": 1, \"trophies\": 0, \"highestTrophies\": 0, \"starPowers\": [], \"gadgets\": [] }, { \"id\": 16000024, \"name\": \"ROSA\", \"power\": 1, \"rank\": 1, \"trophies\": 0, \"highestTrophies\": 0, \"starPowers\": [], \"gadgets\": [] }, { \"id\": 16000025, \"name\": \"CARL\", \"power\": 1, \"rank\": 2, \"trophies\": 10, \"highestTrophies\": 10, \"starPowers\": [], \"gadgets\": [] }, { \"id\": 16000026, \"name\": \"BIBI\", \"power\": 1, \"rank\": 1, \"trophies\": 8, \"highestTrophies\": 8, \"starPowers\": [], \"gadgets\": [] } ] }" + const val RESPONSE_NOT_FOUND: String = "{\"reason\": \"notFound\" }" + const val PLAYER_BATTLE_LOG_RESPONSE: String = "{ \"items\": [ { \"battleTime\": \"20200620T005324.000Z\", \"event\": { \"id\": 15000025, \"mode\": \"brawlBall\", \"map\": \"Triple Dribble\" }, \"battle\": { \"mode\": \"brawlBall\", \"type\": \"ranked\", \"result\": \"victory\", \"duration\": 99, \"trophyChange\": 8, \"starPlayer\": { \"tag\": \"#V2GP99J8\", \"name\": \"JOSEFA\", \"brawler\": { \"id\": 16000001, \"name\": \"COLT\", \"power\": 4, \"trophies\": 105 } }, \"teams\": [ [ { \"tag\": \"#2LUJYLCY0\", \"name\": \"nl7\", \"brawler\": { \"id\": 16000002, \"name\": \"BULL\", \"power\": 5, \"trophies\": 105 } }, { \"tag\": \"#2JPJQVQ9L\", \"name\": \"condecats ruger\", \"brawler\": { \"id\": 16000008, \"name\": \"NITA\", \"power\": 5, \"trophies\": 110 } }, { \"tag\": \"#2YYYRGUGY\", \"name\": \"josepAuLo\", \"brawler\": { \"id\": 16000006, \"name\": \"BARLEY\", \"power\": 5, \"trophies\": 120 } } ], [ { \"tag\": \"#V2GP99J8\", \"name\": \"JOSEFA\", \"brawler\": { \"id\": 16000001, \"name\": \"COLT\", \"power\": 4, \"trophies\": 105 } }, { \"tag\": \"#2GCQU29QV\", \"name\": \"tgd_navi\", \"brawler\": { \"id\": 16000024, \"name\": \"ROSA\", \"power\": 4, \"trophies\": 109 } }, { \"tag\": \"#2JLJURL0P\", \"name\": \"LordWolf\", \"brawler\": { \"id\": 16000008, \"name\": \"NITA\", \"power\": 5, \"trophies\": 110 } } ] ] } }, { \"battleTime\": \"20200620T005053.000Z\", \"event\": { \"id\": 15000025, \"mode\": \"brawlBall\", \"map\": \"Triple Dribble\" }, \"battle\": { \"mode\": \"brawlBall\", \"type\": \"ranked\", \"result\": \"victory\", \"duration\": 73, \"trophyChange\": 8, \"starPlayer\": { \"tag\": \"#C9CVR8LL\", \"name\": \"toddyn\", \"brawler\": { \"id\": 16000037, \"name\": \"SPROUT\", \"power\": 1, \"trophies\": 103 } }, \"teams\": [ [ { \"tag\": \"#V2GP99J8\", \"name\": \"JOSEFA\", \"brawler\": { \"id\": 16000001, \"name\": \"COLT\", \"power\": 4, \"trophies\": 97 } }, { \"tag\": \"#C9CVR8LL\", \"name\": \"toddyn\", \"brawler\": { \"id\": 16000037, \"name\": \"SPROUT\", \"power\": 1, \"trophies\": 103 } }, { \"tag\": \"#2YCPJLU9V\", \"name\": \"Guilherme\", \"brawler\": { \"id\": 16000013, \"name\": \"POCO\", \"power\": 3, \"trophies\": 98 } } ], [ { \"tag\": \"#PJ0PUJGG8\", \"name\": \"fernando06\", \"brawler\": { \"id\": 16000010, \"name\": \"EL PRIMO\", \"power\": 2, \"trophies\": 98 } }, { \"tag\": \"#YRV28VQU\", \"name\": \"Jofre\", \"brawler\": { \"id\": 16000006, \"name\": \"BARLEY\", \"power\": 3, \"trophies\": 106 } }, { \"tag\": \"#9RPJG2ULL\", \"name\": \"ADEXE\", \"brawler\": { \"id\": 16000000, \"name\": \"SHELLY\", \"power\": 3, \"trophies\": 101 } } ] ] } } ], \"paging\": { \"cursors\": {} } }" + const val RESPONSE_UNAUTHORIZED: String = "{ \"reason\": \"accessDenied\", \"message\": \"Invalid authorization\" }" + + @JvmStatic private fun body(body: String): ResponseBody { + return ResponseBody.create(MediaType.parse("application/json"), body) + } + + @JvmStatic fun player(): Response { + return Response.success(Gson().fromJson(PLAYER_RESPONSE_OK, Player::class.java)) + } + + @JvmStatic fun notFound(): Response { + return Response.error(404, body(RESPONSE_NOT_FOUND)) + } + + @JvmStatic fun unauthorized(): Response { + return Response.error(403, body(RESPONSE_UNAUTHORIZED)) + } + + @JvmStatic fun battleLog(): Response { + return Response.success(Gson().fromJson(PLAYER_BATTLE_LOG_RESPONSE, BattleLog::class.java)) + } +} \ No newline at end of file