Skip to content

Commit 6ed73e8

Browse files
authored
Merge pull request #69 from ToDeveloperDo/feature/dev
Feature/dev
2 parents a30acd5 + 4875412 commit 6ed73e8

File tree

16 files changed

+254
-46
lines changed

16 files changed

+254
-46
lines changed

build.gradle.kts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,19 @@ tasks.named<JacocoReport>("jacocoTestReport") {
132132
exclude(
133133
"**/persistence/entity/**",
134134
"**/presentation/**/dto/**",
135-
"**/oauth/apple/dto/**",
136135
"**/oauth/git/dto/**",
136+
"**/dto/request/**",
137+
"**/dto/response/**",
137138
"**/io/junseok/todeveloperdo/oauth/apple/service/serviceimpl/ClientSecretCreator.class",
138139
"**/io/junseok/todeveloperdo/oauth/apple/service/serviceimpl/ClientSecretCreatorTest.class",
139140
"**/io/junseok/todeveloperdo/auth/config/SecurityConfig.class",
140141
"**/io/junseok/todeveloperdo/ToDeveloperDoApplicationKt.class",
141142
"**/io/junseok/todeveloperdo/oauth/git/service/CustomOAuth2UserService.class",
142-
"**/io/junseok/todeveloperdo/global/fcm/FcmCredentials.class"
143+
"**/io/junseok/todeveloperdo/global/fcm/FcmCredentials.class",
144+
"**/io/junseok/todeveloperdo/util/ElvisKt.class",
145+
"**/io/junseok/todeveloperdo/domains/gitissue/TodoCreate*",
146+
"**/io/junseok/todeveloperdo/oauth/git/config/WebhookConfig*",
147+
"**/io/junseok/todeveloperdo/util/StubDateProvider*"
143148
)
144149
}
145150
})

src/main/kotlin/io/junseok/todeveloperdo/auth/jwt/TokenProvider.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ class TokenProvider(
106106
log.info("No refresh token found to delete.")
107107
}
108108
}
109+
else -> {
110+
log.info("ExpiredJwtException occurred, but not a REFRESH token: type=$type")
111+
}
109112
}
110113
throw ToDeveloperDoException { ErrorCode.EXPIRED_JWT }
111114

src/main/kotlin/io/junseok/todeveloperdo/domains/todo/service/MemberTodoService.kt

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ import io.junseok.todeveloperdo.presentation.membertodolist.dto.request.TodoDate
1515
import io.junseok.todeveloperdo.presentation.membertodolist.dto.request.TodoRequest
1616
import io.junseok.todeveloperdo.presentation.membertodolist.dto.response.TodoCountResponse
1717
import io.junseok.todeveloperdo.presentation.membertodolist.dto.response.TodoResponse
18+
import io.junseok.todeveloperdo.util.TimeProvider
19+
import io.junseok.todeveloperdo.util.runIfNotNull
1820
import org.springframework.stereotype.Service
19-
import org.springframework.transaction.annotation.Transactional
20-
import java.time.LocalDate
2121

2222
@Service
2323
class MemberTodoService(
@@ -29,6 +29,7 @@ class MemberTodoService(
2929
private val gitIssueService: GitIssueService,
3030
private val todoValidator: TodoValidator,
3131
private val gitIssueUpdater: GitIssueUpdater,
32+
private val timeProvider: TimeProvider
3233
) {
3334
@CreateEvent
3435
@ReadMeCreate
@@ -40,18 +41,22 @@ class MemberTodoService(
4041
val member = memberReader.getMember(username)
4142

4243
val memberTodoLists = todoRequest.map { todo ->
43-
todoCreator.generatorTodo(
44-
todo,
45-
member,
46-
issueEventRequest?.issueNumber?.get()
47-
?.takeIf { LocalDate.now() == todo.deadline }
48-
)
44+
val issueNumber = issueEventRequest
45+
.runIfNotNull { it.issueNumber }
46+
.runIfNotNull { it.get() }
47+
.runIfNotNull { number ->
48+
if (timeProvider.nowDate() == todo.deadline) number else null
49+
}
50+
51+
todoCreator.generatorTodo(todo, member, issueNumber)
4952
}
53+
5054
val saveTodoList = todoSaver.saveTodoList(memberTodoLists)
5155
gitIssueService.saveGitIssue(member, memberTodoLists)
5256
return saveTodoList
5357
}
5458

59+
5560
// 할 일 찾기
5661
fun findTodoLists(todoDateRequest: TodoDateRequest, username: String): List<TodoResponse> {
5762
val member = memberReader.getMember(username)
@@ -77,7 +82,8 @@ class MemberTodoService(
7782

7883
//할 일 삭제 NOTE
7984
@DeleteEventHandler
80-
fun removeTodoList(todoListId: Long, username: String, state: String) { }
85+
fun removeTodoList(todoListId: Long, username: String, state: String) {
86+
}
8187

8288
fun calculateTodoList(
8389
todoCountRequest: TodoCountRequest,

src/main/kotlin/io/junseok/todeveloperdo/oauth/git/service/GitHubOAuthService.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import io.junseok.todeveloperdo.oauth.git.client.GitHubAccessTokenClient
88
import io.junseok.todeveloperdo.oauth.git.client.GitHubApiClient
99
import io.junseok.todeveloperdo.oauth.git.dto.response.TokenResponse
1010
import io.junseok.todeveloperdo.oauth.git.dto.response.toGitUserResponse
11+
import io.junseok.todeveloperdo.util.runIfNotNull
1112
import org.springframework.beans.factory.annotation.Value
1213
import org.springframework.stereotype.Service
1314

@@ -22,7 +23,7 @@ class GitHubOAuthService(
2223
private val clientSecret: String
2324
) {
2425

25-
fun processGitHubOAuth(code: String,userName: String): TokenResponse {
26+
fun processGitHubOAuth(code: String, userName: String): TokenResponse {
2627
val accessTokenResponse = accessTokenClient.getAccessToken(clientId, clientSecret, code)
2728

2829
if (accessTokenResponse.contains("error")) {
@@ -35,17 +36,25 @@ class GitHubOAuthService(
3536
val userInfoResponse = gitHubApiClient.getUserInfo(bearerToken)
3637

3738
val userInfo = parseUserInfo(userInfoResponse)
38-
memberService.createGitMember(userInfo.toGitUserResponse(),accessToken,userName)
39+
memberService.createGitMember(userInfo.toGitUserResponse(), accessToken, userName)
3940
return TokenResponse(bearerToken)
4041
}
4142

4243
fun extractAccessToken(response: String): String {
43-
val firstOrNull = response.split("&")
44+
return response.split("&")
4445
.firstOrNull { it.startsWith("access_token") }
45-
return (firstOrNull?.split("="))?.get(1)
46-
?: throw IllegalArgumentException("Access token not found in response: $response")
46+
.runIfNotNull { it ->
47+
it.split("=")
48+
.runIfNotNull { it ->
49+
it.getOrNull(1)
50+
.runIfNotNull { token ->
51+
token.takeIf { it.isNotBlank() }
52+
}
53+
}
54+
} ?: throw IllegalArgumentException("Access token not found or malformed: $response")
4755
}
4856

57+
4958
fun parseUserInfo(response: String): Map<String, Any> {
5059
val mapper = jacksonObjectMapper()
5160
return mapper.readValue(response, object : TypeReference<Map<String, Any>>() {})

src/main/kotlin/io/junseok/todeveloperdo/oauth/git/service/reposerviceimpl/WebHookProcessor.kt

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,16 @@ class WebHookProcessor(
1717
if (event == GitHubService.REPOSITORY) {
1818
val action = payload["action"] as String
1919

20-
when (action) {
21-
RENAMED_REPO_ACTION -> {
22-
val payloadResponse = payloadCreator.create(payload)
23-
val member = memberReader.findByGitUserName(payloadResponse.username)
24-
memberUpdater.updateMemberRepo(payloadResponse.newRepoName, member)
25-
}
26-
DELETE_REPO_ACTION -> {
27-
val payloadResponse = payloadCreator.create(payload)
28-
val member = memberReader.findByGitUserName(payloadResponse.username)
29-
memberUpdater.removeMemberRepo(member)
30-
}
20+
if (action == RENAMED_REPO_ACTION) {
21+
val payloadResponse = payloadCreator.create(payload)
22+
val member = memberReader.findByGitUserName(payloadResponse.username)
23+
memberUpdater.updateMemberRepo(payloadResponse.newRepoName, member)
24+
}
25+
if (action == DELETE_REPO_ACTION) {
26+
val payloadResponse = payloadCreator.create(payload)
27+
val member = memberReader.findByGitUserName(payloadResponse.username)
28+
memberUpdater.removeMemberRepo(member)
3129
}
3230
}
3331
}
34-
35-
}
32+
}

src/main/kotlin/io/junseok/todeveloperdo/scheduler/fcm/AllTodosCompletedStrategy.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import org.springframework.stereotype.Component
1212
class AllTodosCompletedStrategy(
1313
private val todoReader: TodoReader,
1414
private val timeProvider: TimeProvider
15-
) : NotificationStrategy{
15+
) : NotificationStrategy {
1616
override fun getFcmRequests(): List<FcmRequest> =
1717
todoReader.findTodoListByTodoStatus(
1818
timeProvider.nowDate(),
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package io.junseok.todeveloperdo.util
2+
3+
inline fun <T, R> T?.runIfNotNull(block: (T) -> R?): R? =
4+
if (this != null) block(this) else null

src/test/kotlin/io/junseok/todeveloperdo/auth/jwt/ExceptionHandlerFilterTest.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,14 @@ class ExceptionHandlerFilterTest : FunSpec({
5353
}
5454
}
5555

56+
test("예외가 발생하지 않으면 필터 체인이 정상적으로 실행된다") {
57+
val request = MockHttpServletRequest()
58+
val response = MockHttpServletResponse()
59+
val chain = mockk<FilterChain>()
60+
61+
every { chain.doFilter(any(), any()) } just runs
62+
63+
filter.doFilter(request, response, chain)
64+
}
5665

5766
})

src/test/kotlin/io/junseok/todeveloperdo/auth/jwt/TokenProviderTest.kt

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import io.jsonwebtoken.SignatureAlgorithm
77
import io.jsonwebtoken.security.Keys
88
import io.junseok.todeveloperdo.auth.jwt.TokenProvider.Companion.AUTHORITIES_KEY
99
import io.junseok.todeveloperdo.domains.member.persistence.repository.MemberRepository
10-
import io.junseok.todeveloperdo.exception.ErrorCode
1110
import io.junseok.todeveloperdo.exception.ErrorCode.EXPIRED_JWT
1211
import io.junseok.todeveloperdo.exception.ToDeveloperDoException
1312
import io.junseok.todeveloperdo.oauth.apple.client.AppleClient
@@ -197,7 +196,7 @@ class TokenProviderTest : FunSpec({
197196
}
198197

199198
test("getAuthentication()에서 권한 문자열에 빈 값이 포함되면 dropLastWhile이 실행된다") {
200-
val authStringWithEmpty = "ROLE_USER," // 마지막이 빈 문자열이 되도록
199+
val authStringWithEmpty = "ROLE_USER,"
201200
val token = Jwts.builder()
202201
.setSubject("testuser")
203202
.setIssuer("TDD")
@@ -221,7 +220,6 @@ class TokenProviderTest : FunSpec({
221220
val applePublicKeys = listOf(createApplePublicKey())
222221

223222
every { appleClient.getApplePublicKeys().keys } returns applePublicKeys
224-
225223
every { AppleJwtUtil.decodeAndVerify(any(), any()) } throws ExpiredJwtException(
226224
null,
227225
null,
@@ -237,4 +235,22 @@ class TokenProviderTest : FunSpec({
237235
}
238236
}
239237

238+
test("ACCESS 타입에서 ExpiredJwtException이 발생하면 else 분기가 실행된다") {
239+
val expiredToken = Jwts.builder()
240+
.setSubject("testuser")
241+
.setIssuer("TDD")
242+
.claim(AUTHORITIES_KEY, "ROLE_USER")
243+
.setExpiration(Date(System.currentTimeMillis() - 10000))
244+
.signWith(tokenProvider.javaClass.getDeclaredField("key").apply {
245+
isAccessible = true
246+
}.get(tokenProvider) as Key, SignatureAlgorithm.HS512)
247+
.compact()
248+
249+
throwsWith<ToDeveloperDoException>({
250+
tokenProvider.validateAppleToken(expiredToken, "ACCESS")
251+
}) {
252+
it.errorCode shouldBe EXPIRED_JWT
253+
}
254+
}
255+
240256
})

src/test/kotlin/io/junseok/todeveloperdo/domains/member/service/serviceimpl/MemberReaderTest.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,11 @@ class MemberReaderTest : BehaviorSpec({
137137
}
138138
})
139139

140-
fun createMember(id: Long, appleId: String, repo: String? = null) = Member(
140+
fun createMember(
141+
id: Long,
142+
appleId: String,
143+
repo: String? = null,
144+
clientToken: String ?="Fcm") = Member(
141145
memberId = id,
142146
appleId = appleId,
143147
appleRefreshToken = "appleRefreshToken",
@@ -147,7 +151,7 @@ fun createMember(id: Long, appleId: String, repo: String? = null) = Member(
147151
gitHubRepo = repo,
148152
avatarUrl = "avatar",
149153
gitHubUrl = "gitUrl",
150-
clientToken = "Fcm",
154+
clientToken = clientToken,
151155
authority = Authority.ROLE_USER
152156
)
153157

0 commit comments

Comments
 (0)