diff --git a/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/image/controller/ImageController.kt b/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/image/controller/ImageController.kt index 86972f34..728115cd 100644 --- a/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/image/controller/ImageController.kt +++ b/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/image/controller/ImageController.kt @@ -27,4 +27,12 @@ class ImageController( ): ImageUrlResponse { return getPresignedUrlUseCase.forPromise(promiseId, fileExtension) } + + @Operation(summary = "유저 프로필 이미지 업로드 Presigned URL 발급") + @GetMapping("/users/me/images") + fun getPresignedUrlOfUser( + @RequestParam fileExtension: ImageFileExtension, + ): ImageUrlResponse { + return getPresignedUrlUseCase.forUser(fileExtension) + } } diff --git a/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/image/usecase/GetPresignedUrlUseCase.kt b/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/image/usecase/GetPresignedUrlUseCase.kt index 0185f333..59188731 100644 --- a/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/image/usecase/GetPresignedUrlUseCase.kt +++ b/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/image/usecase/GetPresignedUrlUseCase.kt @@ -4,6 +4,7 @@ import com.depromeet.whatnow.annotation.UseCase import com.depromeet.whatnow.api.image.dto.ImageUrlResponse import com.depromeet.whatnow.config.s3.ImageFileExtension import com.depromeet.whatnow.config.s3.S3UploadPresignedUrlService +import com.depromeet.whatnow.config.security.SecurityUtils @UseCase class GetPresignedUrlUseCase( @@ -12,4 +13,9 @@ class GetPresignedUrlUseCase( fun forPromise(promiseId: Long, fileExtension: ImageFileExtension): ImageUrlResponse { return ImageUrlResponse.from(presignedUrlService.forPromise(promiseId, fileExtension)) } + + fun forUser(fileExtension: ImageFileExtension): ImageUrlResponse { + val currentUserId = SecurityUtils.currentUserId + return ImageUrlResponse.from(presignedUrlService.forUser(currentUserId, fileExtension)) + } } diff --git a/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/picture/controller/PictureController.kt b/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/picture/controller/PictureController.kt index 56589da3..e4c49434 100644 --- a/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/picture/controller/PictureController.kt +++ b/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/picture/controller/PictureController.kt @@ -21,7 +21,13 @@ class PictureController( @Operation(summary = "약속 관련 이미지 업로드 성공 요청") @PostMapping("/promises/{promiseId}/images/success/{imageKey}") - fun successUploadImage(@PathVariable promiseId: Long, @PathVariable imageKey: String, @RequestParam pictureCommentType: PictureCommentType) { - successUseCase.successUploadImage(promiseId, imageKey, pictureCommentType) + fun promiseUploadImageSuccess(@PathVariable promiseId: Long, @PathVariable imageKey: String, @RequestParam pictureCommentType: PictureCommentType) { + successUseCase.promiseUploadImageSuccess(promiseId, imageKey, pictureCommentType) + } + + @Operation(summary = "유저 프로필 이미지 업로드 성공 요청") + @PostMapping("/users/me/images/success/{imageKey}") + fun userUploadImageSuccess(@PathVariable imageKey: String) { + successUseCase.userUploadImageSuccess(imageKey) } } diff --git a/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/picture/usecase/PictureUploadSuccessUseCase.kt b/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/picture/usecase/PictureUploadSuccessUseCase.kt index 71c7ece0..61db3b72 100644 --- a/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/picture/usecase/PictureUploadSuccessUseCase.kt +++ b/Whatnow-Api/src/main/kotlin/com/depromeet/whatnow/api/picture/usecase/PictureUploadSuccessUseCase.kt @@ -9,8 +9,13 @@ import com.depromeet.whatnow.domains.picture.service.PictureDomainService class PictureUploadSuccessUseCase( val pictureDomainService: PictureDomainService, ) { - fun successUploadImage(promiseId: Long, imageKey: String, pictureCommentType: PictureCommentType) { + fun promiseUploadImageSuccess(promiseId: Long, imageKey: String, pictureCommentType: PictureCommentType) { val currentUserId: Long = SecurityUtils.currentUserId - pictureDomainService.successUploadImage(currentUserId, promiseId, imageKey, pictureCommentType) + pictureDomainService.promiseUploadImageSuccess(currentUserId, promiseId, imageKey, pictureCommentType) + } + + fun userUploadImageSuccess(imageKey: String) { + val currentUserId: Long = SecurityUtils.currentUserId + pictureDomainService.userUploadImageSuccess(currentUserId, imageKey) } } diff --git a/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/image/controller/ImageControllerTest.kt b/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/image/controller/ImageControllerTest.kt index 803663c7..6ff512cb 100644 --- a/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/image/controller/ImageControllerTest.kt +++ b/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/image/controller/ImageControllerTest.kt @@ -23,7 +23,7 @@ class ImageControllerTest { lateinit var mockMvc: MockMvc @Test - fun `presignedUrl 요청에 성공하면 200을 응답한다`() { + fun `약속 이미지 presignedUrl 요청에 성공하면 200을 응답한다`() { // given val promiseId = 1L val fileExtension = ImageFileExtension.JPEG.name @@ -36,4 +36,18 @@ class ImageControllerTest { .andExpect(status().isOk) .andDo { print(it) } } + + @Test + fun `유저 프로필 presignedUrl 요청에 성공하면 200을 응답한다`() { + // given + val fileExtension = ImageFileExtension.JPEG.name + + // when, then + mockMvc.perform( + get("/v1/users/me/images") + .param("fileExtension", fileExtension), + ) + .andExpect(status().isOk) + .andDo { print(it) } + } } diff --git a/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/image/usecase/GetPresignedUrlUseCaseTest.kt b/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/image/usecase/GetPresignedUrlUseCaseTest.kt index 4cde79b6..053e61f8 100644 --- a/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/image/usecase/GetPresignedUrlUseCaseTest.kt +++ b/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/image/usecase/GetPresignedUrlUseCaseTest.kt @@ -4,12 +4,17 @@ import com.depromeet.whatnow.config.s3.ImageFileExtension import com.depromeet.whatnow.config.s3.ImageUrlDto import com.depromeet.whatnow.config.s3.S3UploadPresignedUrlService import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.mockito.InjectMocks import org.mockito.Mock import org.mockito.junit.jupiter.MockitoExtension import org.mockito.kotlin.given +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken +import org.springframework.security.core.authority.SimpleGrantedAuthority +import org.springframework.security.core.context.SecurityContextHolder +import org.springframework.security.test.context.support.WithMockUser @ExtendWith(MockitoExtension::class) class GetPresignedUrlUseCaseTest { @@ -19,8 +24,16 @@ class GetPresignedUrlUseCaseTest { @InjectMocks lateinit var getPresignedUrlUseCase: GetPresignedUrlUseCase + @BeforeEach + fun setup() { + val securityContext = SecurityContextHolder.createEmptyContext() + val authentication = UsernamePasswordAuthenticationToken("1", null, setOf(SimpleGrantedAuthority("ROLE_USER"))) + securityContext.authentication = authentication + SecurityContextHolder.setContext(securityContext) + } + @Test - fun `PresignUrl 을 요청하면 url 을 반환한다`() { + fun `약속 이미지 PresignUrl 을 요청하면 url 을 반환한다`() { // given given(presignedUrlService.forPromise(1, ImageFileExtension.JPEG)).willReturn( ImageUrlDto( @@ -35,4 +48,22 @@ class GetPresignedUrlUseCaseTest { assertEquals("https://whatnow.kr/1.jpg", imageUrlResponse.presignedUrl) assertEquals("1.jpg", imageUrlResponse.key) } + + @Test + @WithMockUser(username = "1") + fun `유저 프로필 PresignUrl 을 요청하면 url 을 반환한다`() { + // given + given(presignedUrlService.forUser(1, ImageFileExtension.JPEG)).willReturn( + ImageUrlDto( + url = "https://whatnow.kr/1.jpg", + key = "1.jpg", + ), + ) + // when + val imageUrlResponse = getPresignedUrlUseCase.forUser(ImageFileExtension.JPEG) + + // then + assertEquals("https://whatnow.kr/1.jpg", imageUrlResponse.presignedUrl) + assertEquals("1.jpg", imageUrlResponse.key) + } } diff --git a/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/picture/controller/PictureControllerTest.kt b/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/picture/controller/PictureControllerTest.kt index 728c0916..314c0257 100644 --- a/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/picture/controller/PictureControllerTest.kt +++ b/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/picture/controller/PictureControllerTest.kt @@ -23,7 +23,7 @@ class PictureControllerTest { lateinit var mockMvc: MockMvc @Test - fun `이미지 업로드 성공 요청에 정상적으로 200을 반환한다`() { + fun `약속 이미지 업로드 성공 요청에 정상적으로 200을 반환한다`() { // given val promiseId = 1 val imageKey = "imageKey" @@ -37,4 +37,17 @@ class PictureControllerTest { .andExpect(status().isOk) .andDo { print(it) } } + + @Test + fun `유저 프로필 업로드 성공 요청에 정상적으로 200을 반환한다`() { + // given + val imageKey = "imageKey" + + // when, then + mockMvc.perform( + post("/v1/users/me/images/success/{imageKey}", imageKey), + ) + .andExpect(status().isOk) + .andDo { print(it) } + } } diff --git a/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/picture/usecase/PictureUploadSuccessUseCaseTest.kt b/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/picture/usecase/PictureUploadSuccessUseCaseTest.kt index 1ae0002e..ce07c96d 100644 --- a/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/picture/usecase/PictureUploadSuccessUseCaseTest.kt +++ b/Whatnow-Api/src/test/kotlin/com/depromeet/whatnow/api/picture/usecase/PictureUploadSuccessUseCaseTest.kt @@ -30,14 +30,26 @@ class PictureUploadSuccessUseCaseTest { } @Test - fun `이미지 업로드 성공 요청시 정상적이라면 에러가 발생하지 않는다`() { + fun `약속 이미지 업로드 성공 요청시 정상적이라면 에러가 발생하지 않는다`() { // given // when // then assertThatCode { - pictureUploadSuccessUseCase.successUploadImage(1, "1", PictureCommentType.SORRY_LATE) + pictureUploadSuccessUseCase.promiseUploadImageSuccess(1, "imageKey", PictureCommentType.SORRY_LATE) + }.doesNotThrowAnyException() + } + + @Test + fun `유저 프로필 업로드 성공 요청시 정상적이라면 에러가 발생하지 않는다`() { + // given + + // when + + // then + assertThatCode { + pictureUploadSuccessUseCase.userUploadImageSuccess("imageKey") }.doesNotThrowAnyException() } } diff --git a/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/adapter/PictureAdapter.kt b/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/adapter/PictureAdapter.kt index 4cc56c32..1b2eecd0 100644 --- a/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/adapter/PictureAdapter.kt +++ b/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/adapter/PictureAdapter.kt @@ -9,8 +9,13 @@ import com.depromeet.whatnow.domains.picture.repository.PictureRepository class PictureAdapter( val pictureRepository: PictureRepository, ) { - fun save(userId: Long, promiseId: Long, imageUrl: String, imageKey: String, pictureCommentType: PictureCommentType) { - val picture = Picture(userId, promiseId, imageUrl, imageKey, pictureCommentType) - pictureRepository.save(picture) + fun saveForPromise(userId: Long, promiseId: Long, imageUrl: String, imageKey: String, pictureCommentType: PictureCommentType): Picture { + val picture = Picture.createForPromise(userId, promiseId, imageUrl, imageKey, pictureCommentType) + return pictureRepository.save(picture) + } + + fun saveForUser(userId: Long, imageUrl: String, imageKey: String): Picture { + val picture = Picture.createForUser(userId, imageUrl, imageKey) + return pictureRepository.save(picture) } } diff --git a/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/domain/Picture.kt b/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/domain/Picture.kt index 9598da1a..ea5db92f 100644 --- a/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/domain/Picture.kt +++ b/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/domain/Picture.kt @@ -25,13 +25,40 @@ class Picture( var uuid: String, @Enumerated(EnumType.STRING) - var pictureCommentType: PictureCommentType, + var pictureType: PictureType, + + @Enumerated(EnumType.STRING) + var pictureCommentType: PictureCommentType = PictureCommentType.NONE, @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "picture_id") val id: Long? = null, ) : BaseTimeEntity() { + companion object { + fun createForPromise(userId: Long, promiseId: Long, url: String, uuid: String, pictureCommentType: PictureCommentType): Picture { + return Picture( + userId = userId, + promiseId = promiseId, + url = url, + uuid = uuid, + pictureType = PictureType.PROMISE, + pictureCommentType = pictureCommentType, + ) + } + + fun createForUser(userId: Long, url: String, uuid: String): Picture { + return Picture( + userId = userId, + promiseId = 0, + url = url, + uuid = uuid, + pictureType = PictureType.USER, + pictureCommentType = PictureCommentType.NONE, + ) + } + } + @PostPersist fun createPictureEvent() { Events.raise(PictureRegisterEvent(userId, promiseId)) diff --git a/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/domain/PictureCommentType.kt b/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/domain/PictureCommentType.kt index 5655e755..cf09743c 100644 --- a/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/domain/PictureCommentType.kt +++ b/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/domain/PictureCommentType.kt @@ -2,7 +2,9 @@ package com.depromeet.whatnow.domains.picture.domain import com.depromeet.whatnow.domains.promiseuser.domain.PromiseUserType -enum class PictureCommentType(val value: String, val promiseUserType: PromiseUserType) { +enum class PictureCommentType(val value: String, val promiseUserType: PromiseUserType?) { + NONE("NONE", null), + // Can LATE RUNNING("달려가는 중️", PromiseUserType.LATE), GASPING("헐레벌떡", PromiseUserType.LATE), diff --git a/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/domain/PictureType.kt b/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/domain/PictureType.kt new file mode 100644 index 00000000..20edec64 --- /dev/null +++ b/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/domain/PictureType.kt @@ -0,0 +1,5 @@ +package com.depromeet.whatnow.domains.picture.domain + +enum class PictureType { + PROMISE, USER +} diff --git a/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/service/PictureDomainService.kt b/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/service/PictureDomainService.kt index 040e9477..be077291 100644 --- a/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/service/PictureDomainService.kt +++ b/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/picture/service/PictureDomainService.kt @@ -8,6 +8,7 @@ import com.depromeet.whatnow.domains.picture.exception.InvalidCommentTypeExcepti import com.depromeet.whatnow.domains.picture.exception.UploadBeforeTrackingException import com.depromeet.whatnow.domains.promiseuser.adaptor.PromiseUserAdaptor import com.depromeet.whatnow.domains.promiseuser.domain.PromiseUserType +import com.depromeet.whatnow.domains.user.adapter.UserAdapter import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -15,14 +16,22 @@ import org.springframework.transaction.annotation.Transactional class PictureDomainService( val pictureAdapter: PictureAdapter, val promiseUserAdapter: PromiseUserAdaptor, + val userAdapter: UserAdapter, ) { @Transactional - fun successUploadImage(userId: Long, promiseId: Long, imageKey: String, pictureCommentType: PictureCommentType) { + fun promiseUploadImageSuccess(userId: Long, promiseId: Long, imageKey: String, pictureCommentType: PictureCommentType) { val promiseUser = promiseUserAdapter.findByPromiseIdAndUserId(promiseId, userId) validatePromiseUserType(promiseUser.promiseUserType!!, pictureCommentType) val imageUrl = IMAGE_DOMAIN + "promise/$promiseId/$imageKey" - pictureAdapter.save(userId, promiseId, imageUrl, imageKey, pictureCommentType) + pictureAdapter.saveForPromise(userId, promiseId, imageUrl, imageKey, pictureCommentType) + } + + fun userUploadImageSuccess(userId: Long, imageKey: String) { + val user = userAdapter.queryUser(userId) + val imageUrl = IMAGE_DOMAIN + "user/$userId/$imageKey" + pictureAdapter.saveForUser(userId, imageUrl, imageKey) + user.updateProfileImg(imageUrl) } private fun validatePromiseUserType(promiseUserType: PromiseUserType, pictureCommentType: PictureCommentType) { diff --git a/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/user/domain/User.kt b/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/user/domain/User.kt index 45ebf09f..aa2db305 100644 --- a/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/user/domain/User.kt +++ b/Whatnow-Domain/src/main/kotlin/com/depromeet/whatnow/domains/user/domain/User.kt @@ -98,6 +98,14 @@ class User( profileImg = profileImage nickname = username } + + fun updateProfileImg(imageUrl: String) { + if (profileImg != imageUrl) { + isDefaultImg = false + } + profileImg = imageUrl + } + fun toUserInfoVo(): UserInfoVo { return UserInfoVo.from(this) } diff --git a/Whatnow-Domain/src/test/kotlin/com/depromeet/whatnow/domains/picture/adapter/PictureAdapterTest.kt b/Whatnow-Domain/src/test/kotlin/com/depromeet/whatnow/domains/picture/adapter/PictureAdapterTest.kt index 6f6e4dfe..16e1a193 100644 --- a/Whatnow-Domain/src/test/kotlin/com/depromeet/whatnow/domains/picture/adapter/PictureAdapterTest.kt +++ b/Whatnow-Domain/src/test/kotlin/com/depromeet/whatnow/domains/picture/adapter/PictureAdapterTest.kt @@ -2,15 +2,16 @@ package com.depromeet.whatnow.domains.picture.adapter import com.depromeet.whatnow.domains.picture.domain.Picture import com.depromeet.whatnow.domains.picture.domain.PictureCommentType +import com.depromeet.whatnow.domains.picture.domain.PictureType import com.depromeet.whatnow.domains.picture.repository.PictureRepository import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith -import org.mockito.ArgumentCaptor import org.mockito.InjectMocks import org.mockito.Mock import org.mockito.Mockito import org.mockito.junit.jupiter.MockitoExtension -import org.mockito.kotlin.then +import org.mockito.kotlin.given +import kotlin.test.assertEquals @ExtendWith(MockitoExtension::class) class PictureAdapterTest { @@ -21,13 +22,36 @@ class PictureAdapterTest { lateinit var pictureAdapter: PictureAdapter @Test - fun `Picture 저장 시 정상적으로 저장된다`() { - val captor: ArgumentCaptor = ArgumentCaptor.forClass(Picture::class.java) + fun `약속 이미지 Picture 저장 시 정상적으로 저장된다`() { + given(pictureRepository.save(Mockito.any(Picture::class.java))) + .willReturn(Picture.createForPromise(1, 1, "imageUrl", "imageKey", PictureCommentType.RUNNING)) // when - pictureAdapter.save(1, 1, "imageUrl", "imageKey", PictureCommentType.RUNNING) + val picture = pictureAdapter.saveForPromise(1, 1, "imageUrl", "imageKey", PictureCommentType.RUNNING) // then - then(pictureRepository).should(Mockito.times(1)).save(captor.capture()) + assertEquals(picture.userId, 1) + assertEquals(picture.promiseId, 1) + assertEquals(picture.url, "imageUrl") + assertEquals(picture.uuid, "imageKey") + assertEquals(picture.pictureType, PictureType.PROMISE) + assertEquals(picture.pictureCommentType, PictureCommentType.RUNNING) + } + + @Test + fun `유저 프로필 Picture 저장 시 정상적으로 저장된다`() { + given(pictureRepository.save(Mockito.any(Picture::class.java))) + .willReturn(Picture.createForUser(1, "imageUrl", "imageKey")) + + // when + val picture = pictureAdapter.saveForUser(1, "imageUrl", "imageKey") + + // then + assertEquals(picture.userId, 1) + assertEquals(picture.promiseId, 0) + assertEquals(picture.url, "imageUrl") + assertEquals(picture.uuid, "imageKey") + assertEquals(picture.pictureType, PictureType.USER) + assertEquals(picture.pictureCommentType, PictureCommentType.NONE) } } diff --git a/Whatnow-Domain/src/test/kotlin/com/depromeet/whatnow/domains/picture/service/PictureDomainServiceTest.kt b/Whatnow-Domain/src/test/kotlin/com/depromeet/whatnow/domains/picture/service/PictureDomainServiceTest.kt index 38e52af2..983b9d01 100644 --- a/Whatnow-Domain/src/test/kotlin/com/depromeet/whatnow/domains/picture/service/PictureDomainServiceTest.kt +++ b/Whatnow-Domain/src/test/kotlin/com/depromeet/whatnow/domains/picture/service/PictureDomainServiceTest.kt @@ -9,6 +9,8 @@ import com.depromeet.whatnow.domains.picture.exception.UploadBeforeTrackingExcep import com.depromeet.whatnow.domains.promiseuser.adaptor.PromiseUserAdaptor import com.depromeet.whatnow.domains.promiseuser.domain.PromiseUser import com.depromeet.whatnow.domains.promiseuser.domain.PromiseUserType +import com.depromeet.whatnow.domains.user.adapter.UserAdapter +import com.depromeet.whatnow.helper.user_id_1_fixture import org.assertj.core.api.Assertions import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -26,11 +28,14 @@ class PictureDomainServiceTest { @Mock lateinit var promiseUserAdapter: PromiseUserAdaptor + @Mock + lateinit var userAdapter: UserAdapter + @InjectMocks lateinit var pictureDomainService: PictureDomainService @Test - fun `사진 업로드 성공 요청시 정상적이라면 에러를 반환하지 않는다`() { + fun `약속 이미지 업로드 성공 요청시 정상적이라면 에러를 반환하지 않는다`() { // given val promiseUser = PromiseUser( promiseId = 1, @@ -43,12 +48,12 @@ class PictureDomainServiceTest { // when, then Assertions.assertThatCode { - pictureDomainService.successUploadImage(1, 1, "imageKey", PictureCommentType.RUNNING) + pictureDomainService.promiseUploadImageSuccess(1, 1, "imageKey", PictureCommentType.RUNNING) }.doesNotThrowAnyException() } @Test - fun `유저가 READY 상태라면 예외가 발생한다`() { + fun `약속 이미지 업로드 성공 요청시 유저가 READY 상태라면 예외가 발생한다`() { // given val promiseUser = PromiseUser( promiseId = 1, @@ -61,12 +66,12 @@ class PictureDomainServiceTest { // when, then Assertions.assertThatThrownBy { - pictureDomainService.successUploadImage(1, 1, "imageKey", PictureCommentType.RUNNING) + pictureDomainService.promiseUploadImageSuccess(1, 1, "imageKey", PictureCommentType.RUNNING) }.isInstanceOf(UploadBeforeTrackingException::class.java) } @Test - fun `유저가 CANCEL 상태라면 예외가 발생한다`() { + fun `약속 이미지 업로드 성공 요청시 유저가 CANCEL 상태라면 예외가 발생한다`() { // given val promiseUser = PromiseUser( promiseId = 1, @@ -79,12 +84,12 @@ class PictureDomainServiceTest { // when, then Assertions.assertThatThrownBy { - pictureDomainService.successUploadImage(1, 1, "imageKey", PictureCommentType.RUNNING) + pictureDomainService.promiseUploadImageSuccess(1, 1, "imageKey", PictureCommentType.RUNNING) }.isInstanceOf(CancelledUserUploadException::class.java) } @Test - fun `LATE 유저가 WAIT 타입의 코멘트를 입력 할 경우 예외가 발생한다`() { + fun `약속 이미지 업로드 성공 요청시 LATE 유저가 WAIT 타입의 코멘트를 입력 할 경우 예외가 발생한다`() { // given val promiseUser = PromiseUser( promiseId = 1, @@ -97,12 +102,12 @@ class PictureDomainServiceTest { // when, then Assertions.assertThatThrownBy { - pictureDomainService.successUploadImage(1, 1, "imageKey", PictureCommentType.DID_YOU_COME) + pictureDomainService.promiseUploadImageSuccess(1, 1, "imageKey", PictureCommentType.DID_YOU_COME) }.isInstanceOf(InvalidCommentTypeException::class.java) } @Test - fun `WAIT 유저가 LATE 타입의 코멘트를 입력 할 경우 예외가 발생한다`() { + fun `약속 이미지 업로드 성공 요청시 WAIT 유저가 LATE 타입의 코멘트를 입력 할 경우 예외가 발생한다`() { // given val promiseUser = PromiseUser( promiseId = 1, @@ -115,7 +120,19 @@ class PictureDomainServiceTest { // when, then Assertions.assertThatThrownBy { - pictureDomainService.successUploadImage(1, 1, "imageKey", PictureCommentType.WAIT_A_BIT) + pictureDomainService.promiseUploadImageSuccess(1, 1, "imageKey", PictureCommentType.WAIT_A_BIT) }.isInstanceOf(InvalidCommentTypeException::class.java) } + + @Test + fun `유저 프로필 업로드 성공 요청시 정상적이라면 에러를 반환하지 않는다`() { + // given + given(userAdapter.queryUser(anyLong())) + .willReturn(user_id_1_fixture()) + + // when, then + Assertions.assertThatCode { + pictureDomainService.userUploadImageSuccess(1, "imageKey") + }.doesNotThrowAnyException() + } } diff --git a/Whatnow-Domain/src/test/kotlin/com/depromeet/whatnow/events/handler/PictureRegisterEventHandlerTest.kt b/Whatnow-Domain/src/test/kotlin/com/depromeet/whatnow/events/handler/PictureRegisterEventHandlerTest.kt index 1b9c9d48..1d5fb732 100644 --- a/Whatnow-Domain/src/test/kotlin/com/depromeet/whatnow/events/handler/PictureRegisterEventHandlerTest.kt +++ b/Whatnow-Domain/src/test/kotlin/com/depromeet/whatnow/events/handler/PictureRegisterEventHandlerTest.kt @@ -33,7 +33,7 @@ class PictureRegisterEventHandlerTest { given(promiseUserAdaptor.findByPromiseIdAndUserId(1, 1)).willReturn(promiseUser) // when - pictureDomainService.successUploadImage(1, 1, "imageKey", PictureCommentType.RUNNING) + pictureDomainService.promiseUploadImageSuccess(1, 1, "imageKey", PictureCommentType.RUNNING) // then then(pictureRegisterEventHandler).should(Mockito.times(1)).handleRegisterPictureEvent(any()) diff --git a/Whatnow-Infrastructure/src/main/kotlin/com/depromeet/whatnow/config/s3/S3UploadPresignedUrlService.kt b/Whatnow-Infrastructure/src/main/kotlin/com/depromeet/whatnow/config/s3/S3UploadPresignedUrlService.kt index 31fe7ea7..1553bef4 100644 --- a/Whatnow-Infrastructure/src/main/kotlin/com/depromeet/whatnow/config/s3/S3UploadPresignedUrlService.kt +++ b/Whatnow-Infrastructure/src/main/kotlin/com/depromeet/whatnow/config/s3/S3UploadPresignedUrlService.kt @@ -25,10 +25,24 @@ class S3UploadPresignedUrlService( return ImageUrlDto(generatePresignedUrl.toString(), uuid) } + fun forUser(userId: Long, fileExtension: ImageFileExtension): ImageUrlDto { + val uuid = UUID.randomUUID().toString() + var fileName = getForUserFimeName(uuid, userId, fileExtension) + val generatePresignedUrlRequest = + getGeneratePreSignedUrlRequest(s3Secret.bucket, fileName, fileExtension.uploadExtension) + + val generatePresignedUrl = amazonS3.generatePresignedUrl(generatePresignedUrlRequest) + return ImageUrlDto(generatePresignedUrl.toString(), uuid) + } + private fun getForPromiseFimeName(uuid: String, promiseId: Long, fileExtension: ImageFileExtension): String { return "promise/" + promiseId + "/" + uuid + "." + fileExtension.uploadExtension } + private fun getForUserFimeName(uuid: String, userId: Long, fileExtension: ImageFileExtension): String { + return "user/" + userId + "/" + uuid + "." + fileExtension.uploadExtension + } + private fun getGeneratePreSignedUrlRequest( bucket: String, fileName: String, diff --git a/Whatnow-Infrastructure/src/test/kotlin/com/depromeet/whatnow/config/s3/S3UploadPresignedUrlServiceTest.kt b/Whatnow-Infrastructure/src/test/kotlin/com/depromeet/whatnow/config/s3/S3UploadPresignedUrlServiceTest.kt index 55894b31..69383ebd 100644 --- a/Whatnow-Infrastructure/src/test/kotlin/com/depromeet/whatnow/config/s3/S3UploadPresignedUrlServiceTest.kt +++ b/Whatnow-Infrastructure/src/test/kotlin/com/depromeet/whatnow/config/s3/S3UploadPresignedUrlServiceTest.kt @@ -37,7 +37,7 @@ class S3UploadPresignedUrlServiceTest { } @Test - fun `PresignedUrl을 생성한다`() { + fun `약속 이미지 PresignedUrl을 생성한다`() { // given val promiseId = 1L val imageFIleExtension = ImageFileExtension.JPG @@ -50,4 +50,19 @@ class S3UploadPresignedUrlServiceTest { assertContains(presignedUrl.url, resultUrl) } + + @Test + fun `유저 프로필 PresignedUrl을 생성한다`() { + // given + val userId = 1L + val imageFIleExtension = ImageFileExtension.JPG + + // when + val presignedUrl = s3UploadPresignedUrlService.forUser(userId, imageFIleExtension) + + // then + val resultUrl = "https://${s3Properties.s3.bucket}.${s3Properties.s3.endpoint.replace("https://", "")}/user/$userId/${presignedUrl.key}.${imageFIleExtension.uploadExtension}" + + assertContains(presignedUrl.url, resultUrl) + } }