-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
d5d8c1a
commit 3a86a87
Showing
9 changed files
with
215 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
src/main/kotlin/kr/galaxyhub/sc/common/support/WebClientErrorHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package kr.galaxyhub.sc.common.support | ||
|
||
import io.github.oshai.kotlinlogging.KotlinLogging | ||
import kr.galaxyhub.sc.common.exception.GalaxyhubException | ||
import kr.galaxyhub.sc.common.exception.InternalServerError | ||
import reactor.core.publisher.Mono | ||
|
||
private val log = KotlinLogging.logger {} | ||
|
||
fun <T> Mono<T>.handleConnectError( | ||
exMessage: String = "외부 서버와 연결 중 문제가 발생했습니다.", | ||
): Mono<T> { | ||
return onErrorResume({ it !is GalaxyhubException }) { | ||
log.error(it) { exMessage } | ||
Mono.error(InternalServerError(exMessage)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
package kr.galaxyhub.sc.auth.infra | ||
|
||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper | ||
import io.kotest.assertions.throwables.shouldThrow | ||
import io.kotest.core.spec.IsolationMode | ||
import io.kotest.core.spec.style.DescribeSpec | ||
import io.kotest.matchers.shouldBe | ||
import io.kotest.matchers.throwable.shouldHaveMessage | ||
import java.time.Duration | ||
import java.util.concurrent.TimeUnit | ||
import kr.galaxyhub.sc.common.exception.BadRequestException | ||
import kr.galaxyhub.sc.common.exception.InternalServerError | ||
import kr.galaxyhub.sc.common.support.enqueue | ||
|
@@ -13,29 +15,32 @@ import org.springframework.web.reactive.function.client.WebClient | |
|
||
class DiscordOAuth2ClientTest : DescribeSpec({ | ||
|
||
val objectMapper = jacksonObjectMapper() | ||
isolationMode = IsolationMode.InstancePerLeaf | ||
|
||
val mockWebServer = MockWebServer() | ||
val discordOAuth2Client = DiscordOAuth2Client( | ||
webClient = WebClient.builder() | ||
.baseUrl("${mockWebServer.url("/")}") | ||
.build(), | ||
clientId = "client_id", | ||
clientSecret = "client_secret", | ||
redirectUri = "https://sc.galaxyhub.kr" | ||
redirectUri = "https://sc.galaxyhub.kr", | ||
timeoutDuration = Duration.ofSeconds(10) | ||
) | ||
|
||
describe("getAccessToken") { | ||
val response = DiscordAccessTokenResponse( | ||
accessToken = "123123", | ||
tokenType = "Bearer", | ||
expiresIn = 3000, | ||
refreshToken = "321321", | ||
scope = "email" | ||
) | ||
|
||
context("외부 서버가 200 응답을 반환하면") { | ||
val response = DiscordAccessTokenResponse( | ||
accessToken = "123123", | ||
tokenType = "Bearer", | ||
expiresIn = 3000, | ||
refreshToken = "321321", | ||
scope = "email" | ||
) | ||
mockWebServer.enqueue { | ||
statusCode(200) | ||
body(objectMapper.writeValueAsString(response)) | ||
body(response) | ||
} | ||
|
||
val actual = response.accessToken | ||
|
@@ -72,19 +77,51 @@ class DiscordOAuth2ClientTest : DescribeSpec({ | |
ex shouldHaveMessage "Discord OAuth2 서버에 문제가 발생했습니다." | ||
} | ||
} | ||
|
||
context("외부 서버에 연결할 수 없으면") { | ||
mockWebServer.shutdown() | ||
|
||
it("InternalServerError 예외를 던진다.") { | ||
val ex = shouldThrow<InternalServerError> { discordOAuth2Client.getAccessToken("code") } | ||
ex shouldHaveMessage "Discord OAuth2 서버와 연결 중 문제가 발생했습니다." | ||
} | ||
} | ||
|
||
context("외부 서버에 지연이 발생하면") { | ||
val delayClient = DiscordOAuth2Client( | ||
webClient = WebClient.builder() | ||
.baseUrl("${mockWebServer.url("/")}") | ||
.build(), | ||
clientId = "client_id", | ||
clientSecret = "client_secret", | ||
redirectUri = "https://sc.galaxyhub.kr", | ||
timeoutDuration = Duration.ofMillis(100) | ||
) | ||
mockWebServer.enqueue { | ||
statusCode(200) | ||
body(response) | ||
delay(10, TimeUnit.SECONDS) | ||
} | ||
|
||
it("InternalServerError 예외를 던진다.") { | ||
val ex = shouldThrow<InternalServerError> { delayClient.getAccessToken("code") } | ||
ex shouldHaveMessage "Discord OAuth2 서버의 응답 시간이 초과되었습니다." | ||
} | ||
} | ||
} | ||
|
||
describe("getUserInfo") { | ||
val response = DiscordUserInfoResponse( | ||
id = "12345", | ||
username = "seokjin8678", | ||
email = "[email protected]", | ||
avatar = "avatar", | ||
) | ||
|
||
context("외부 서버가 200 응답을 반환하면") { | ||
val response = DiscordUserInfoResponse( | ||
id = "12345", | ||
username = "seokjin8678", | ||
email = "[email protected]", | ||
avatar = "avatar", | ||
) | ||
mockWebServer.enqueue { | ||
statusCode(200) | ||
body(objectMapper.writeValueAsString(response)) | ||
body(response) | ||
} | ||
|
||
val actual = response.toUserInfo() | ||
|
@@ -116,6 +153,37 @@ class DiscordOAuth2ClientTest : DescribeSpec({ | |
ex shouldHaveMessage "Discord OAuth2 서버에 문제가 발생했습니다." | ||
} | ||
} | ||
|
||
context("외부 서버에 연결할 수 없으면") { | ||
mockWebServer.shutdown() | ||
|
||
it("InternalServerError 예외를 던진다.") { | ||
val ex = shouldThrow<InternalServerError> { discordOAuth2Client.getUserInfo("accessToken") } | ||
ex shouldHaveMessage "Discord OAuth2 서버와 연결 중 문제가 발생했습니다." | ||
} | ||
} | ||
|
||
context("외부 서버에 지연이 발생하면") { | ||
val delayClient = DiscordOAuth2Client( | ||
webClient = WebClient.builder() | ||
.baseUrl("${mockWebServer.url("/")}") | ||
.build(), | ||
clientId = "client_id", | ||
clientSecret = "client_secret", | ||
redirectUri = "https://sc.galaxyhub.kr", | ||
timeoutDuration = Duration.ofMillis(100) | ||
) | ||
mockWebServer.enqueue { | ||
statusCode(200) | ||
body(response) | ||
delay(10, TimeUnit.SECONDS) | ||
} | ||
|
||
it("InternalServerError 예외를 던진다.") { | ||
val ex = shouldThrow<InternalServerError> { delayClient.getUserInfo("accessToken") } | ||
ex shouldHaveMessage "Discord OAuth2 서버의 응답 시간이 초과되었습니다." | ||
} | ||
} | ||
} | ||
}) | ||
|
Oops, something went wrong.