Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge: (#202) MultipartFile → File 변환 리팩토링 #203

Merged
merged 8 commits into from
Dec 10, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package team.comit.simtong.domain.file.usecase

import team.comit.simtong.domain.file.FileExtensionUtils.isImageExtension
import team.comit.simtong.domain.file.exception.FileInvalidExtensionException
import team.comit.simtong.domain.file.spi.UploadFilePort
import team.comit.simtong.global.annotation.UseCase
import java.io.File
Expand All @@ -20,25 +18,11 @@ class UploadImageUseCase(
) {

fun execute(file: File): String {
if (!isImageExtension(file)) {
file.delete()
throw FileInvalidExtensionException.EXCEPTION
}

return uploadFilePort.upload(file)
}

fun execute(files: List<File>): List<String> {
files.forEach {
if (!isImageExtension(it)) {
files.deleteAll()
throw FileInvalidExtensionException.EXCEPTION
}
}

return uploadFilePort.upload(files)
}

private fun List<File>.deleteAll() = this.forEach(File::delete)

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package team.comit.simtong.domain.file.usecase
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.mockito.BDDMockito.given
import org.springframework.boot.test.mock.mockito.MockBean
import team.comit.simtong.domain.file.exception.FileInvalidExtensionException
import team.comit.simtong.domain.file.spi.UploadFilePort
import team.comit.simtong.global.annotation.SimtongTest
import java.io.File
Expand All @@ -21,15 +19,13 @@ class UploadImageUseCaseTests {

private val filePathStub = "test path"

private val filePathListStub = listOf(filePathStub)

private val jpgFileStub by lazy { File("test.jpg") }

private val jpegFileStub by lazy { File("test.jpeg") }

private val pngFileStub by lazy { File("test.png") }
private val fileStub: File by lazy {
File("test.jpg")
}

private val svgFileStub by lazy { File("test.svg") }
private val filesStub: List<File> by lazy {
listOf(fileStub)
}

@BeforeEach
fun setUp() {
Expand All @@ -39,50 +35,29 @@ class UploadImageUseCaseTests {
@Test
fun `단일 이미지 업로드`() {
// given
given(managerFilePort.upload(jpgFileStub))
given(managerFilePort.upload(fileStub))
.willReturn(filePathStub)

given(managerFilePort.upload(jpegFileStub))
.willReturn(filePathStub)
// when
val response = uploadImageUseCase.execute(fileStub)

given(managerFilePort.upload(pngFileStub))
.willReturn(filePathStub)
// then
assertEquals(response, filePathStub)

// when & then
assertEquals(uploadImageUseCase.execute(jpgFileStub), filePathStub)
assertEquals(uploadImageUseCase.execute(jpegFileStub), filePathStub)
assertEquals(uploadImageUseCase.execute(pngFileStub), filePathStub)
}

@Test
fun `다중 이미지 업로드`() {
// given
val filesStub = listOf(jpgFileStub, jpegFileStub, pngFileStub)
val filePathListStub = listOf(filePathStub)

given(managerFilePort.upload(filesStub))
.willReturn(filePathListStub)

// when & then
assertEquals(uploadImageUseCase.execute(filesStub), filePathListStub)
}

@Test
fun `단일 파일 확장자 오류`() {
// when & then
assertThrows<FileInvalidExtensionException> {
uploadImageUseCase.execute(svgFileStub)
}
}

@Test
fun `다중 파일 확장자 오류`() {
// given
val files = listOf(jpgFileStub, jpegFileStub, pngFileStub, svgFileStub)
// when
val response = uploadImageUseCase.execute(filesStub)

// when & then
assertThrows<FileInvalidExtensionException> {
uploadImageUseCase.execute(files)
}
assertEquals(response, filePathListStub)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile
import team.comit.simtong.domain.file.dto.response.UploadImageListWebResponse
import team.comit.simtong.domain.file.dto.response.UploadImageWebResponse
import team.comit.simtong.domain.file.transfer.ExcelFileConvertor
import team.comit.simtong.domain.file.transfer.ImageFileConvertor
import team.comit.simtong.domain.file.usecase.RegisterEmployeeCertificateUseCase
import team.comit.simtong.domain.file.usecase.UploadImageUseCase
import java.io.File
import java.io.FileOutputStream
import java.util.UUID

/**
*
Expand All @@ -33,31 +32,28 @@ class WebFileAdapter(
@ResponseStatus(HttpStatus.CREATED)
fun uploadSingleImage(file: MultipartFile): UploadImageWebResponse {
return UploadImageWebResponse(
uploadImageUseCase.execute(file.let(transferFile))
uploadImageUseCase.execute(
file.let(ImageFileConvertor::transferTo)
)
)
}

@PostMapping("/list")
@ResponseStatus(HttpStatus.CREATED)
fun uploadMultipleImage(files: List<MultipartFile>): UploadImageListWebResponse {
return UploadImageListWebResponse(
uploadImageUseCase.execute(files.map(transferFile))
uploadImageUseCase.execute(
files.let(ImageFileConvertor::transferToList)
)
)
}

@PostMapping("/employee")
@ResponseStatus(HttpStatus.CREATED)
fun importEmployeeCertificate(file: MultipartFile) {
registerEmployeeCertificateUseCase.execute(file.let(transferFile))
}

private val transferFile = { multipartFile: MultipartFile ->
File("${UUID.randomUUID()}_${multipartFile.originalFilename}").apply {
FileOutputStream(this).run {
write(multipartFile.bytes)
close()
}
}
registerEmployeeCertificateUseCase.execute(
file.let(ExcelFileConvertor::transferTo)
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package team.comit.simtong.domain.file.transfer

import org.springframework.web.multipart.MultipartFile
import team.comit.simtong.domain.file.FileExtensionUtils.XLS
import team.comit.simtong.domain.file.FileExtensionUtils.XLSX

/**
*
* Excel File의 변환을 담당하는 ExcelFileConvertor
*
* @author Chokyunghyeon
* @date 2022/12/09
* @version 1.0.0
**/
object ExcelFileConvertor : FileConvertor {

override fun isCorrectExtension(multipartFile: MultipartFile): Boolean {
return when (multipartFile.extension) {
XLS, XLSX -> true
else -> false
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package team.comit.simtong.domain.file.transfer

import org.springframework.web.multipart.MultipartFile
import team.comit.simtong.domain.file.exception.FileInvalidExtensionException
import java.io.File
import java.io.FileOutputStream
import java.util.UUID

/**
*
* MultipartFile에서 File의 변환을 담당하는 FileConvertor
*
* @author Chokyunghyeon
* @date 2022/12/09
* @version 1.0.0
**/
interface FileConvertor {

val MultipartFile.extension: String
get() = originalFilename?.substringAfterLast(".", "")?.uppercase() ?: ""


fun isCorrectExtension(multipartFile: MultipartFile): Boolean

fun transferTo(multipartFile: MultipartFile): File {
if (!isCorrectExtension(multipartFile)) {
throw FileInvalidExtensionException.EXCEPTION
}

return transferFile(multipartFile)
}

fun transferToList(multipartFiles: List<MultipartFile>): List<File> {
multipartFiles.forEach {
if (!isCorrectExtension(it)) {
throw FileInvalidExtensionException.EXCEPTION
}
}

return multipartFiles.map(this::transferFile)
}

private fun transferFile(multipartFile: MultipartFile): File {
return File("${UUID.randomUUID()}_${multipartFile.originalFilename}")
.apply {
FileOutputStream(this).run {
write(multipartFile.bytes)
close()
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package team.comit.simtong.domain.file.transfer

import org.springframework.web.multipart.MultipartFile
import team.comit.simtong.domain.file.FileExtensionUtils.HEIC
import team.comit.simtong.domain.file.FileExtensionUtils.JPEG
import team.comit.simtong.domain.file.FileExtensionUtils.JPG
import team.comit.simtong.domain.file.FileExtensionUtils.PNG

/**
*
* Image File의 변환을 담당하는 ImageFileConvertor
*
* @author Chokyunghyeon
* @date 2022/12/09
* @version 1.0.0
**/
object ImageFileConvertor : FileConvertor {

override fun isCorrectExtension(multipartFile: MultipartFile): Boolean {
return when (multipartFile.extension) {
JPG, JPEG, PNG, HEIC -> true
else -> false
}
}

}