From c1ad5b1dc42dd51210f874a3644570b39fee1c15 Mon Sep 17 00:00:00 2001 From: Wooyeol Lee Date: Thu, 23 Nov 2023 17:36:53 +0900 Subject: [PATCH] feat: feat thumbnail in EmojiAPI --- .../emoji/controller/EmojiController.kt | 3 ++- .../springboot/domain/emoji/dao/EmojiDao.kt | 17 ++++++++++--- .../springboot/domain/emoji/dto/EmojiDto.kt | 4 +++- .../domain/emoji/service/EmojiService.kt | 4 ++-- .../emoji/controller/EmojiControllerTest.kt | 5 +++- .../domain/emoji/dao/EmojiDaoTest.kt | 24 +++++++++++++------ .../domain/emoji/service/EmojiServiceTest.kt | 10 ++++---- 7 files changed, 48 insertions(+), 19 deletions(-) diff --git a/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/controller/EmojiController.kt b/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/controller/EmojiController.kt index f1f037cb..e4db9c31 100644 --- a/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/controller/EmojiController.kt +++ b/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/controller/EmojiController.kt @@ -17,9 +17,10 @@ class EmojiController(private val emojiService: EmojiService) { fun postEmoji( @CurrentUser username: String, @RequestPart(value = "file") file: MultipartFile, + @RequestPart(value = "thumbnail") thumbnail: MultipartFile, @RequestPart postEmojiRequest: PostEmojiRequest ): ResponseEntity { - return ResponseEntity(emojiService.postEmoji(username, file, postEmojiRequest.emoji_unicode, postEmojiRequest.emoji_label), HttpStatus.CREATED) + return ResponseEntity(emojiService.postEmoji(username, file, thumbnail, postEmojiRequest.emoji_unicode, postEmojiRequest.emoji_label), HttpStatus.CREATED) } @GetMapping diff --git a/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/dao/EmojiDao.kt b/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/dao/EmojiDao.kt index 64f565a3..f4de0422 100644 --- a/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/dao/EmojiDao.kt +++ b/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/dao/EmojiDao.kt @@ -6,6 +6,7 @@ import com.google.cloud.storage.BlobId import com.google.cloud.storage.BlobInfo import com.google.cloud.storage.Storage import lombok.extern.slf4j.Slf4j +import org.apache.http.entity.ContentType import org.springframework.stereotype.Repository import org.springframework.web.multipart.MultipartFile import java.io.ByteArrayInputStream @@ -50,11 +51,12 @@ class EmojiDao( return document.toObject(EmojiDto::class.java) } - fun insertEmoji(username: String, file: MultipartFile, emojiUnicode: String, emojiLabel: String, dateTime: String): EmojiDto { + fun insertEmoji(username: String, file: MultipartFile, thumbnail: MultipartFile, emojiUnicode: String, emojiLabel: String, dateTime: String): EmojiDto { // NOTE: created_by(username)을 video이름으로 넣어주어 유저별로 올린 비디오를 구분할 수 있게 한다. + val blobIdPart = username + "_" + dateTime val emojiVideoBlobId: BlobId = BlobId.of( EMOJI_STORAGE_BUCKET_NAME, - username + "_" + dateTime + ".mp4" + "$blobIdPart.mp4" ) val emojiVideoBlob: BlobInfo = BlobInfo.newBuilder(emojiVideoBlobId) .setContentType("video/mp4") @@ -62,7 +64,16 @@ class EmojiDao( storage.createFrom(emojiVideoBlob, ByteArrayInputStream(file.bytes)) val emojiVideoUrl = storage.get(emojiVideoBlobId).signUrl(100, TimeUnit.DAYS) // upload video thumbnail to emojiBucket - val emoji = EmojiDto(username, emojiUnicode, emojiLabel, emojiVideoUrl.toString(), dateTime) + val thumbnailBlobId: BlobId = BlobId.of( + EMOJI_STORAGE_BUCKET_NAME, + "$blobIdPart.jpeg" + ) + val thumbnailBlob: BlobInfo = BlobInfo.newBuilder(thumbnailBlobId) + .setContentType(ContentType.IMAGE_JPEG.toString()) + .build() + storage.createFrom(thumbnailBlob, ByteArrayInputStream(thumbnail.bytes)) + val thumbnailUrl = storage.get(thumbnailBlobId).signUrl(100, TimeUnit.DAYS) + val emoji = EmojiDto(username, emojiUnicode, emojiLabel, emojiVideoUrl.toString(), dateTime, thumbnailUrl.toString()) db.collection(EMOJI_COLLECTION_NAME) .document(emoji.id) .set(emoji) diff --git a/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/dto/EmojiDto.kt b/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/dto/EmojiDto.kt index f0e60e65..45b09c3e 100644 --- a/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/dto/EmojiDto.kt +++ b/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/dto/EmojiDto.kt @@ -10,8 +10,9 @@ data class EmojiDto( var emoji_label: String = "", var created_at: String = "", var num_saved: Int = 0, + var thumbnail_url: String = "" ){ - constructor(username: String, emojiUnicode: String, emojiLabel: String, emojiVideoUrl: String, dateTime: String) : this() { + constructor(username: String, emojiUnicode: String, emojiLabel: String, emojiVideoUrl: String, dateTime: String, thumbnailUrl: String) : this() { val source = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" val outputStrLength: Long = 20 id = java.util.Random().ints(outputStrLength, 0, source.length) @@ -25,5 +26,6 @@ data class EmojiDto( emoji_label = emojiLabel created_at = dateTime num_saved = 0 + thumbnail_url = thumbnailUrl } } \ No newline at end of file diff --git a/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/service/EmojiService.kt b/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/service/EmojiService.kt index d5a7a4c5..696824b0 100644 --- a/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/service/EmojiService.kt +++ b/springboot/src/main/kotlin/com/goliath/emojihub/springboot/domain/emoji/service/EmojiService.kt @@ -34,9 +34,9 @@ class EmojiService( return emojiDao.getEmoji(emojiId) } - fun postEmoji(username: String, file: MultipartFile, emojiUnicode: String, emojiLabel: String) { + fun postEmoji(username: String, file: MultipartFile, thumbnail: MultipartFile, emojiUnicode: String, emojiLabel: String) { val dateTime = getDateTimeNow() - val emoji = emojiDao.insertEmoji(username, file, emojiUnicode, emojiLabel, dateTime) + val emoji = emojiDao.insertEmoji(username, file, thumbnail, emojiUnicode, emojiLabel, dateTime) userDao.insertId(username, emoji.id, CREATED_EMOJIS) } diff --git a/springboot/src/test/kotlin/com/goliath/emojihub/springboot/domain/emoji/controller/EmojiControllerTest.kt b/springboot/src/test/kotlin/com/goliath/emojihub/springboot/domain/emoji/controller/EmojiControllerTest.kt index c74c4462..f2472879 100644 --- a/springboot/src/test/kotlin/com/goliath/emojihub/springboot/domain/emoji/controller/EmojiControllerTest.kt +++ b/springboot/src/test/kotlin/com/goliath/emojihub/springboot/domain/emoji/controller/EmojiControllerTest.kt @@ -135,6 +135,8 @@ internal class EmojiControllerTest @Autowired constructor( // given val audioContent = ByteArray(100) val audioFile = MockMultipartFile("file", "test.mp4", "audio/mp4", audioContent) + val imageContent = ByteArray(100) + val thumbnail = MockMultipartFile("thumbnail", "test.jpeg", "image/jpeg", imageContent) val request = PostEmojiRequest( emoji_unicode = "test_emoji_unicode", emoji_label = "test_emoji_label" @@ -151,6 +153,7 @@ internal class EmojiControllerTest @Autowired constructor( val result = mockMvc.perform( multipart("/api/emoji") .file(audioFile) + .file(thumbnail) .file(requestFile) .contentType(MediaType.MULTIPART_FORM_DATA) .characterEncoding("UTF-8") @@ -160,7 +163,7 @@ internal class EmojiControllerTest @Autowired constructor( // then result.andExpect(status().isCreated) - verify(emojiService, times(1)).postEmoji(any(), any(), any(), any()) + verify(emojiService, times(1)).postEmoji(any(), any(), any(), any(), any()) } @Test diff --git a/springboot/src/test/kotlin/com/goliath/emojihub/springboot/domain/emoji/dao/EmojiDaoTest.kt b/springboot/src/test/kotlin/com/goliath/emojihub/springboot/domain/emoji/dao/EmojiDaoTest.kt index a8195d7d..5afc9984 100644 --- a/springboot/src/test/kotlin/com/goliath/emojihub/springboot/domain/emoji/dao/EmojiDaoTest.kt +++ b/springboot/src/test/kotlin/com/goliath/emojihub/springboot/domain/emoji/dao/EmojiDaoTest.kt @@ -44,7 +44,7 @@ internal class EmojiDaoTest { lateinit var blob: Blob @MockBean - lateinit var emojiURL: URL + lateinit var url: URL companion object { @@ -84,6 +84,7 @@ internal class EmojiDaoTest { id = "test_emoji" + i + "_" + j, created_by = "test_username$i", video_url = "test_video_url" + i + "_" + j, + thumbnail_url = "test_thumbnail_url" + i + "_" + j, emoji_unicode = "test_emoji_unicode" + i + "_" + j, emoji_label = "test_emoji_label" + i + "_" + j, created_at = "test_created_at" + i + "_" + j, @@ -144,26 +145,35 @@ internal class EmojiDaoTest { val username = userList[1].username val audioContent = ByteArray(100) val file = MockMultipartFile("file", "test.mp4", "audio/mp4", audioContent) + val imageContent = ByteArray(100) + val thumbnail = MockMultipartFile("thumbnail", "test.jpeg", "image/jpeg", imageContent) val emojiUnicode = "test_emoji_unicode" val emojiLabel = "test_emoji_label" - val emojiVideoUrl = "test_emoji_video_url" + val url = "test_url" val dateTime = "test_date_time" + val blobIdPart = username + "_" + dateTime val emojiVideoBlobId: BlobId = BlobId.of( "emojihub-e2023.appspot.com", - username + "_" + dateTime + ".mp4" + "$blobIdPart.mp4" + ) + val thumbnailBlobId: BlobId = BlobId.of( + "emojihub-e2023.appspot.com", + "$blobIdPart.jpeg" ) Mockito.`when`(db.collection(EMOJI_COLLECTION_NAME)) .thenReturn(testDB.collection(EMOJI_COLLECTION_NAME)) Mockito.`when`(storage.get(emojiVideoBlobId)).thenReturn(blob) - Mockito.`when`(blob.signUrl(100, TimeUnit.DAYS)).thenReturn(emojiURL) - Mockito.`when`(emojiURL.toString()).thenReturn(emojiVideoUrl) + Mockito.`when`(storage.get(thumbnailBlobId)).thenReturn(blob) + Mockito.`when`(blob.signUrl(100, TimeUnit.DAYS)).thenReturn(this.url) + Mockito.`when`(this.url.toString()).thenReturn(url) // when - val result = emojiDao.insertEmoji(username, file, emojiUnicode, emojiLabel, dateTime) + val result = emojiDao.insertEmoji(username, file, thumbnail, emojiUnicode, emojiLabel, dateTime) // then verify(storage, times(1)).get(emojiVideoBlobId) - verify(blob, times(1)).signUrl(100, TimeUnit.DAYS) + verify(storage, times(1)).get(thumbnailBlobId) + verify(blob, times(2)).signUrl(100, TimeUnit.DAYS) var emojiExist = emojiDao.existsEmoji(result.id) var a = 1 diff --git a/springboot/src/test/kotlin/com/goliath/emojihub/springboot/domain/emoji/service/EmojiServiceTest.kt b/springboot/src/test/kotlin/com/goliath/emojihub/springboot/domain/emoji/service/EmojiServiceTest.kt index 013ab6e3..7cda3e84 100644 --- a/springboot/src/test/kotlin/com/goliath/emojihub/springboot/domain/emoji/service/EmojiServiceTest.kt +++ b/springboot/src/test/kotlin/com/goliath/emojihub/springboot/domain/emoji/service/EmojiServiceTest.kt @@ -121,6 +121,8 @@ internal class EmojiServiceTest { val username = "test_username" val audioContent = ByteArray(100) val file = MockMultipartFile("file", "test.mp4", "audio/mp4", audioContent) + val imageContent = ByteArray(100) + val thumbnail = MockMultipartFile("thumbnail", "test.jpeg", "image/jpeg", imageContent) val emojiUnicode = "test_emoji_unicode" val emojiLabel = "test_emoji_label" val emoji = EmojiDto( @@ -132,14 +134,14 @@ internal class EmojiServiceTest { created_at = "test_created_at", num_saved = 0, ) - Mockito.`when`(emojiDao.insertEmoji(any(), any(), any(), any(), any())).thenReturn(emoji) + Mockito.`when`(emojiDao.insertEmoji(any(), any(), any(), any(), any(), any())).thenReturn(emoji) // when - emojiService.postEmoji(username, file, emojiUnicode, emojiLabel) + emojiService.postEmoji(username, file, thumbnail, emojiUnicode, emojiLabel) // then - verify(emojiDao, times(1)).insertEmoji(any(), any(), any(), any(), any()) - verify(emojiDao, times(1)).insertEmoji(any(), any(), any(), any(), any()) + verify(emojiDao, times(1)).insertEmoji(any(), any(), any(), any(), any(), any()) + verify(userDao, times(1)).insertId(username, emoji.id, "created_emojis") } @Test