Skip to content
This repository was archived by the owner on Jul 7, 2025. It is now read-only.

Commit a953035

Browse files
committed
ASAP-456 비회원 이미지 업로드 로직 리팩토링 및 테스트 개선
- `ImageMetadata.owner`를 nullable로 변경하여 비회원 지원. - 비회원 이미지 업로드 시 기본 ID("anonymous") 설정 로직을 `S3ImageManagementAdapter`로 이동. - `upload` 메서드의 비회원 처리 로직 단순화. - `ImageCommandServiceTest` 테스트 구조 개선: 시나리오 분리 및 검증 추가. - `ImageMetadata` 데이터 클래스 구조 수정.
1 parent c4449da commit a953035

4 files changed

Lines changed: 24 additions & 35 deletions

File tree

Application-Module/src/main/kotlin/com/asap/application/image/service/ImageCommandService.kt

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,13 @@ class ImageCommandService(
1212
private val imageManagementPort: ImageManagementPort,
1313
private val userManagementPort: UserManagementPort,
1414
) : UploadImageUsecase {
15-
companion object {
16-
private const val ANONYMOUS_OWNER_ID = "anonymous"
17-
}
18-
1915
override fun upload(command: UploadImageUsecase.Command): UploadImageUsecase.Response {
20-
val owner =
21-
when {
22-
command.userId != null -> {
23-
val user = userManagementPort.getUserNotNull(DomainId(command.userId))
24-
user.id.value
25-
}
26-
27-
else -> ANONYMOUS_OWNER_ID
28-
}
16+
val user = command.userId?.let { userManagementPort.getUserNotNull(DomainId(it)) }
2917

3018
val uploadedImage =
3119
imageManagementPort.save(
3220
ImageMetadata(
33-
owner = owner,
21+
owner = user?.id?.value,
3422
fileMetaData = command.image,
3523
),
3624
)

Application-Module/src/main/kotlin/com/asap/application/image/vo/ImageMetadata.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.asap.application.image.vo
33
import com.asap.common.file.FileMetaData
44

55
data class ImageMetadata(
6-
val owner: String,
7-
val fileMetaData: FileMetaData
8-
) {
9-
}
6+
val owner: String?,
7+
val fileMetaData: FileMetaData,
8+
)

Application-Module/src/test/kotlin/com/asap/application/image/service/ImageCommandServiceTest.kt

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,21 @@ package com.asap.application.image.service
22

33
import com.asap.application.image.port.`in`.UploadImageUsecase
44
import com.asap.application.image.port.out.ImageManagementPort
5-
import com.asap.application.image.vo.ImageMetadata
65
import com.asap.application.image.vo.UploadedImage
76
import com.asap.application.user.port.out.UserManagementPort
87
import com.asap.common.file.FileMetaData
98
import com.asap.domain.UserFixture
9+
import io.kotest.core.spec.IsolationMode
1010
import io.kotest.core.spec.style.BehaviorSpec
1111
import io.kotest.matchers.nulls.shouldNotBeNull
12-
import io.kotest.matchers.shouldBe
1312
import io.mockk.every
1413
import io.mockk.mockk
15-
import io.mockk.slot
1614
import io.mockk.verify
1715
import java.io.InputStream
1816

1917
class ImageCommandServiceTest :
2018
BehaviorSpec({
19+
isolationMode = IsolationMode.InstancePerLeaf
2120

2221
val mockImageManagementPort = mockk<ImageManagementPort>(relaxed = true)
2322
val mockUserManagementPort = mockk<UserManagementPort>(relaxed = true)
@@ -28,10 +27,11 @@ class ImageCommandServiceTest :
2827
mockUserManagementPort,
2928
)
3029

31-
given("익명 사용자의 이미지 업로드 요청이 들어올 때") {
30+
given("이미지 업로드 요청이 들어올 때") {
31+
val mockUser = UserFixture.createUser()
3232
val command =
3333
UploadImageUsecase.Command(
34-
userId = null,
34+
userId = mockUser.id.value,
3535
image =
3636
FileMetaData(
3737
name = "name",
@@ -40,12 +40,14 @@ class ImageCommandServiceTest :
4040
inputStream = InputStream.nullInputStream(),
4141
),
4242
)
43-
val imageMetadataSlot = slot<ImageMetadata>()
4443
every {
45-
mockImageManagementPort.save(capture(imageMetadataSlot))
44+
mockUserManagementPort.getUserNotNull(any())
45+
} returns mockUser
46+
every {
47+
mockImageManagementPort.save(any())
4648
} returns
4749
UploadedImage(
48-
imageUrl = "anonymousImageUrl",
50+
imageUrl = "imageUrl",
4951
)
5052
`when`("이미지 업로드 요청을 처리하면") {
5153
val response = imageCommandService.upload(command)
@@ -54,17 +56,14 @@ class ImageCommandServiceTest :
5456
this.isNotBlank()
5557
this.isNotEmpty()
5658
}
57-
verify { mockImageManagementPort.save(any()) }
58-
imageMetadataSlot.captured.owner shouldBe "anonymous"
5959
}
6060
}
6161
}
6262

63-
given("이미지 업로드 요청이 들어올 때") {
64-
val mockUser = UserFixture.createUser()
63+
given("userId가 null인 이미지 업로드 요청이 들어올 때") {
6564
val command =
6665
UploadImageUsecase.Command(
67-
userId = mockUser.id.value,
66+
userId = null,
6867
image =
6968
FileMetaData(
7069
name = "name",
@@ -73,9 +72,6 @@ class ImageCommandServiceTest :
7372
inputStream = InputStream.nullInputStream(),
7473
),
7574
)
76-
every {
77-
mockUserManagementPort.getUserNotNull(any())
78-
} returns mockUser
7975
every {
8076
mockImageManagementPort.save(any())
8177
} returns
@@ -84,6 +80,9 @@ class ImageCommandServiceTest :
8480
)
8581
`when`("이미지 업로드 요청을 처리하면") {
8682
val response = imageCommandService.upload(command)
83+
then("getUserNotNull 메서드가 호출되지 않아야 한다") {
84+
verify(exactly = 0) { mockUserManagementPort.getUserNotNull(any()) }
85+
}
8786
then("이미지가 저장되어야 한다") {
8887
response.imageUrl shouldNotBeNull {
8988
this.isNotBlank()

Infrastructure-Module/AWS/src/main/kotlin/com/asap/aws/s3/S3ImageManagementAdapter.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ class S3ImageManagementAdapter(
1313
private val s3Template: S3Template,
1414
) : ImageManagementPort {
1515
override fun save(image: ImageMetadata): UploadedImage {
16-
val key = "${image.owner}/${UUID.randomUUID()}"
16+
val owner = image.owner ?: ANONYMOUS_OWNER_ID
17+
18+
val key = "$owner/${UUID.randomUUID()}"
1719

1820
val resource =
1921
s3Template.upload(
@@ -33,5 +35,6 @@ class S3ImageManagementAdapter(
3335

3436
companion object {
3537
private const val BUCKET_NAME = "lettering-images"
38+
private const val ANONYMOUS_OWNER_ID = "anonymous"
3639
}
3740
}

0 commit comments

Comments
 (0)