From 417b543d3de7db909c63b025cd6694a47aedfbac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Fri, 31 Oct 2025 14:25:29 +0900 Subject: [PATCH 01/16] =?UTF-8?q?feat:=20=EC=95=A8=EB=B2=94=20=EC=99=B8=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/controller/ImageController.java | 8 +++++ .../dto/request/ImageConfirmRequest.java | 9 ++++++ .../image/exception/ImageErrorCode.java | 1 + .../domain/image/service/ImageService.java | 2 ++ .../image/service/ImageServiceImpl.java | 7 ++++ .../main/java/org/cherrypic/s3/S3Util.java | 32 +++++++++++++++++++ 6 files changed, 59 insertions(+) create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageConfirmRequest.java diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java index 105739a7..6c26c7b5 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java @@ -51,6 +51,14 @@ public PresignedUrlResponse eventCoverImageUploadUrlCreate( return imageService.createEventCoverImageUploadUrl(request); } + @PostMapping("/image/confirm-non-album") + @Operation(summary = "앨범 사진 외 사진 검증", description = "프로필, 커버 사진 등의 이미지 업로드를 검증합니다.") + public ResponseEntity nonAlbumImageConfirm( + @Valid @RequestBody ImageConfirmRequest request) { + imageService.confirmNonAlbumImage(request); + return ResponseEntity.noContent().build(); + } + @PostMapping("/albums/{albumId}/images") @Operation( summary = "앨범 이미지 업로드 Presigned URL들 생성", diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageConfirmRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageConfirmRequest.java new file mode 100644 index 00000000..3a503212 --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageConfirmRequest.java @@ -0,0 +1,9 @@ +package org.cherrypic.domain.image.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; + +public record ImageConfirmRequest( + @NotBlank(message = "이미지 url을 비워둘 수 없습니다.") + @Schema(description = "검증하고자 하는 이미지 url", example = "https://example.jpg") + String imageUrl) {} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/exception/ImageErrorCode.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/exception/ImageErrorCode.java index 1166ff8a..6f905c17 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/exception/ImageErrorCode.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/exception/ImageErrorCode.java @@ -11,6 +11,7 @@ public enum ImageErrorCode implements BaseErrorCode { IMAGE_DELETED(409, "이미지 관련 작업 중 이미지가 삭제되었습니다."), IMAGE_CONFLICT(409, "예상치 못한 이미지 무결성 오류"), NOT_IMAGE_EXTENSION(400, "프로필과 커버에는 이미지 파일만 업로드 가능합니다."), + IMAGE_UPLOAD_FAIL(400, "이미지가 성공적으로 업로드 되지 못했습니다."), PRESIGNED_IMAGES_NOT_MINE(403, "본인이 업로드하지 않은 Presigned Image는 삭제할 수 없습니다."), DUPLICATE_HASHES(400, "중복되는 md5 해시값이 존재합니다."); diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java index 9cc9abd3..cb7f22d1 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java @@ -36,4 +36,6 @@ TempAlbumImageUploadListResponse createTempAlbumImageUploadUrls( Long tempAlbumId, TempAlbumImageUploadRequest request); void deleteTempAlbumImage(Long tempAlbumId, TempAlbumImageDeleteRequest request); + + void confirmNonAlbumImage(ImageConfirmRequest request); } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java index 98e59e10..7ee716bb 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java @@ -333,6 +333,13 @@ public void deleteTempAlbumImage(Long tempAlbumId, TempAlbumImageDeleteRequest r tempAlbumImageRepository.deleteAllInBatch(tempAlbumImages); } + @Override + public void confirmNonAlbumImage(ImageConfirmRequest request) { + if (!s3Util.doesFileExistByUrl(request.imageUrl())) { + throw new CustomException(ImageErrorCode.IMAGE_UPLOAD_FAIL); + } + } + private Album getAlbumById(Long albumId) { return albumRepository .findById(albumId) diff --git a/cherrypic-infrastructure/src/main/java/org/cherrypic/s3/S3Util.java b/cherrypic-infrastructure/src/main/java/org/cherrypic/s3/S3Util.java index 1a0b4fb7..0069c560 100644 --- a/cherrypic-infrastructure/src/main/java/org/cherrypic/s3/S3Util.java +++ b/cherrypic-infrastructure/src/main/java/org/cherrypic/s3/S3Util.java @@ -1,6 +1,7 @@ package org.cherrypic.s3; import com.amazonaws.HttpMethod; +import com.amazonaws.SdkClientException; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.Headers; import com.amazonaws.services.s3.model.*; @@ -61,11 +62,42 @@ private GeneratePresignedUrlRequest generatePresignedUrlRequest( generatePresignedUrlRequest.addRequestParameter( Headers.S3_CANNED_ACL, CannedAccessControlList.PublicRead.toString()); + generatePresignedUrlRequest.addRequestParameter("x-amz-tagging", "status=pending"); + generatePresignedUrlRequest.setContentMd5(base64Md5); return generatePresignedUrlRequest; } + public void updateTagToCompleteByUrl(String url) { + String bucket = s3Properties.bucket(); + String key = extractObjectKey(url); + + List tags = List.of(new Tag("status", "complete")); + ObjectTagging tagging = new ObjectTagging(tags); + + SetObjectTaggingRequest request = new SetObjectTaggingRequest(bucket, key, tagging); + amazonS3.setObjectTagging(request); + } + + public boolean doesFileExistByUrl(String url) { + String bucket = s3Properties.bucket(); + String key = extractObjectKey(url); + try { + return amazonS3.doesObjectExist(bucket, key); + } catch (AmazonS3Exception e) { + if (e.getStatusCode() == 403) { + log.warn("Access denied for key={}, treating as non-existent", key); + return false; + } + log.error("S3 error while checking existence: {}", e.getErrorMessage(), e); + return false; + } catch (SdkClientException e) { + log.error("Network error while connecting to S3: {}", e.getMessage()); + return false; + } + } + public void deleteAllByUrls(List urls) { if (urls == null || urls.isEmpty()) { log.info("deleteAllByUrls skipped: received null or empty urls"); From 9b1b811c0814734748f901510407cd31e4394d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Fri, 31 Oct 2025 14:34:38 +0900 Subject: [PATCH 02/16] =?UTF-8?q?test:=20controller=20test=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/controller/ImageController.java | 2 +- .../image/controller/ImageControllerTest.java | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java index 6c26c7b5..3eea64b3 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java @@ -52,7 +52,7 @@ public PresignedUrlResponse eventCoverImageUploadUrlCreate( } @PostMapping("/image/confirm-non-album") - @Operation(summary = "앨범 사진 외 사진 검증", description = "프로필, 커버 사진 등의 이미지 업로드를 검증합니다.") + @Operation(summary = "앨범 사진 외 이미지 검증", description = "프로필, 커버 사진 등의 이미지 업로드를 검증합니다.") public ResponseEntity nonAlbumImageConfirm( @Valid @RequestBody ImageConfirmRequest request) { imageService.confirmNonAlbumImage(request); diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index c943ba35..d5467fd2 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -1763,4 +1763,72 @@ class 임시_앨범_이미지_삭제_요청_시 { .value("삭제하고자 하는 임시 앨범 이미지 ID들은 비워둘 수 없습니다.")); } } + + @Nested + class 앨범_외_이미지_업로드_검증_요청_시 { + + @Test + void 유효한_요청이면_NO_CONTENT를_반환한다() throws Exception { + // given + ImageConfirmRequest request = new ImageConfirmRequest("testImageUrl"); + + willDoNothing().given(imageService).confirmNonAlbumImage(request); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/image/confirm-non-album") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isNoContent()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.status").value(HttpStatus.NO_CONTENT.value())); + } + + @Test + void 이미지_업로드_실패_시_예외가_발생한다() throws Exception { + // given + ImageConfirmRequest request = new ImageConfirmRequest("testImageUrl"); + + willThrow(new CustomException(ImageErrorCode.IMAGE_UPLOAD_FAIL)) + .given(imageService) + .confirmNonAlbumImage(request); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/image/confirm-non-album") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.data.code").value("IMAGE_UPLOAD_FAIL")) + .andExpect(jsonPath("$.data.message").value("이미지가 성공적으로 업로드 되지 못했습니다.")); + } + + @ParameterizedTest + @NullSource + @EmptySource + @ValueSource(strings = {" "}) + void 이미지_url을_비워두면_예외가_발생한다(String imageUrl) throws Exception { + // given + ImageConfirmRequest request = new ImageConfirmRequest(imageUrl); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/image/confirm-non-album") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.data.code").value("MethodArgumentNotValidException")) + .andExpect(jsonPath("$.data.message").value("이미지 url을 비워둘 수 없습니다.")); + } + } } From 5b1e34c919da01ec4fea7d1f1c295a4ceac18726 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Fri, 31 Oct 2025 14:48:07 +0900 Subject: [PATCH 03/16] =?UTF-8?q?test:=20service=20test=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/service/ImageServiceTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java index 72f0e216..168927f0 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java @@ -1,6 +1,7 @@ package org.cherrypic.image.service; import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.mockito.ArgumentMatchers.*; import static org.mockito.BDDMockito.given; @@ -1251,4 +1252,30 @@ void setUp() { .hasMessage(TempAlbumErrorCode.IMAGES_NOT_IN_TEMP_ALBUM.getMessage()); } } + + @Nested + class 앨범_외_이미지_업로드를_검증할_때 { + + @Test + void 업로드_성공_시_예외가_발생하지_않는다() { + // given + ImageConfirmRequest request = new ImageConfirmRequest("testImageUrl"); + given(s3Util.doesFileExistByUrl("testImageUrl")).willReturn(true); + + // when & then + assertDoesNotThrow(() -> imageService.confirmNonAlbumImage(request)); + } + + @Test + void 업로드_실패_시_예외가_발생한다() { + // given + ImageConfirmRequest request = new ImageConfirmRequest("testImageUrl"); + given(s3Util.doesFileExistByUrl("testImageUrl")).willReturn(false); + + // when & then + assertThatThrownBy(() -> imageService.confirmNonAlbumImage(request)) + .isInstanceOf(CustomException.class) + .hasMessage(ImageErrorCode.IMAGE_UPLOAD_FAIL.getMessage()); + } + } } From 4a9fe14e4b7e5381ecc59796da8e71b45c19b2d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Fri, 31 Oct 2025 15:40:57 +0900 Subject: [PATCH 04/16] =?UTF-8?q?feat:=20=EC=95=A8=EB=B2=94=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/controller/ImageController.java | 15 ++- .../dto/request/AlbumImageUploadRequest.java | 2 - .../request/AlbumImagesConfirmRequest.java | 27 +++++ .../response/AlbumImageUploadResponse.java | 11 ++ .../response/AlbumImagesConfirmResponse.java | 12 ++ .../dto/response/ImageUploadListResponse.java | 21 ---- .../domain/image/service/ImageService.java | 7 +- .../image/service/ImageServiceImpl.java | 110 +++++++++++------- .../image/controller/ImageControllerTest.java | 4 +- .../image/service/ImageServiceTest.java | 4 +- .../main/java/org/cherrypic/s3/S3Util.java | 17 +++ 11 files changed, 154 insertions(+), 76 deletions(-) create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadResponse.java create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesConfirmResponse.java delete mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImageUploadListResponse.java diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java index 3eea64b3..298fcba5 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java @@ -52,10 +52,10 @@ public PresignedUrlResponse eventCoverImageUploadUrlCreate( } @PostMapping("/image/confirm-non-album") - @Operation(summary = "앨범 사진 외 이미지 검증", description = "프로필, 커버 사진 등의 이미지 업로드를 검증합니다.") - public ResponseEntity nonAlbumImageConfirm( + @Operation(summary = "앨범 사진 외 이미지 업로드 검증", description = "프로필, 커버 사진 등의 이미지 업로드를 검증합니다.") + public ResponseEntity nonAlbumImageUploadConfirm( @Valid @RequestBody ImageConfirmRequest request) { - imageService.confirmNonAlbumImage(request); + imageService.confirmNonAlbumImageUpload(request); return ResponseEntity.noContent().build(); } @@ -63,11 +63,18 @@ public ResponseEntity nonAlbumImageConfirm( @Operation( summary = "앨범 이미지 업로드 Presigned URL들 생성", description = "앨범 이미지 업로드를 위한 Presigned URL들을 생성합니다.") - public ImageUploadListResponse albumImageUploadUrlsCreate( + public AlbumImageUploadResponse albumImageUploadUrlsCreate( @PathVariable Long albumId, @Valid @RequestBody AlbumImageUploadRequest request) { return imageService.createAlbumImageUploadUrls(albumId, request); } + @PostMapping("/album/{albumId}/confirm-images-upload") + @Operation(summary = "앨범 이미지 업로드 검증", description = "앨범 이미지들의 업로드를 검증합니다.") + public AlbumImagesConfirmResponse albumImagesUploadConfirm( + @PathVariable Long albumId, @Valid @RequestBody AlbumImagesConfirmRequest request) { + return imageService.confirmAlbumImagesUpload(albumId, request); + } + @GetMapping("/albums/{albumId}/images") @Operation(summary = "앨범 이미지 목록 조회", description = "앨범의 이미지 목록을 조회합니다.") public SliceResponse albumImagesGet( diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadRequest.java index d5b16529..deac84a4 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadRequest.java @@ -6,7 +6,6 @@ import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import java.math.BigDecimal; -import java.time.LocalDateTime; import java.util.List; import org.cherrypic.global.annotation.Enum; import org.cherrypic.s3.enums.FileExtension; @@ -25,7 +24,6 @@ public record Payload( @NotBlank(message = "MD5 해시값은 비워둘 수 없습니다.") @Schema(description = "S3 업로드시 파일의 변형을 확인하기 위한 md5 해시") String md5Hashes, - @Schema(description = "파일이 찍힌 시간, 정보가 없다면 null을 넣어주세요.") LocalDateTime generatedAt, @NotNull(message = "파일의 용량은 비워둘 수 없습니다.") @Schema(description = "업로드 하는 파일의 용량(MB), 소수점 2자리 까지", example = "0.04") BigDecimal capacityMb) {} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java new file mode 100644 index 00000000..7f859c7f --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java @@ -0,0 +1,27 @@ +package org.cherrypic.domain.image.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + +public record AlbumImagesConfirmRequest( + @NotEmpty(message = "검증하고자 하는 이미지들의 정보들은 비워둘 수 없습니다.") + @Valid + @Schema(description = "검증 요청 리스트") + List payloads) { + @Schema(name = "AlbumImagesConfirmPayload") + public record Payload( + String md5Hashes, + @Schema(description = "파일이 찍힌 시간, 정보가 없다면 null을 넣어주세요.") LocalDateTime generatedAt, + @NotNull(message = "파일의 용량은 비워둘 수 없습니다.") + @Schema(description = "업로드 하는 파일의 용량(MB), 소수점 2자리 까지", example = "0.04") + BigDecimal capacityMb, + @NotEmpty(message = "검증하고자 하는 imageUrl은 비워둘 수 없습니다.") + @Valid + @Schema(description = "검증 요청 이미지 Url") + String imageUrl) {} +} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadResponse.java new file mode 100644 index 00000000..2bd44d68 --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadResponse.java @@ -0,0 +1,11 @@ +package org.cherrypic.domain.image.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; + +public record AlbumImageUploadResponse( + @Schema(description = "생성된 presigned url 리스트", example = "1") List urls) { + public static AlbumImageUploadResponse of(List urls) { + return new AlbumImageUploadResponse(urls); + } +} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesConfirmResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesConfirmResponse.java new file mode 100644 index 00000000..cb6c40d9 --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesConfirmResponse.java @@ -0,0 +1,12 @@ +package org.cherrypic.domain.image.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; + +public record AlbumImagesConfirmResponse( + @Schema(description = "로컬 사진 삭제 허용 여부") Boolean localImageDeletion, + @Schema(description = "생성된 이미지들의 ID 리스트") List imageIds) { + public static AlbumImagesConfirmResponse of(List imageIds, Boolean localImageDeletion) { + return new AlbumImagesConfirmResponse(localImageDeletion, imageIds); + } +} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImageUploadListResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImageUploadListResponse.java deleted file mode 100644 index 0b020806..00000000 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImageUploadListResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.cherrypic.domain.image.dto.response; - -import io.swagger.v3.oas.annotations.media.Schema; -import java.util.List; - -public record ImageUploadListResponse( - @Schema(description = "로컬 사진 삭제 허용 여부") Boolean localImageDeletion, - @Schema(description = "업로드된 이미지들의 정보 리스트") List content) { - public static ImageUploadListResponse of(List content, Boolean localImageDeletion) { - return new ImageUploadListResponse(localImageDeletion, content); - } - - @Schema(name = "ImageUploadListResponseContent") - public record Content( - @Schema(description = "생성된 이미지의 ID") Long imageId, - @Schema(description = "생성된 Presigned Url") String presignedUrl) { - public static Content of(Long imageId, String presignedUrl) { - return new Content(imageId, presignedUrl); - } - } -} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java index cb7f22d1..977b4cd9 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java @@ -13,7 +13,7 @@ public interface ImageService { PresignedUrlResponse createEventCoverImageUploadUrl(ImageUploadRequest request); - ImageUploadListResponse createAlbumImageUploadUrls( + AlbumImageUploadResponse createAlbumImageUploadUrls( Long albumId, AlbumImageUploadRequest request); SliceResponse getAlbumImages( @@ -37,5 +37,8 @@ TempAlbumImageUploadListResponse createTempAlbumImageUploadUrls( void deleteTempAlbumImage(Long tempAlbumId, TempAlbumImageDeleteRequest request); - void confirmNonAlbumImage(ImageConfirmRequest request); + void confirmNonAlbumImageUpload(ImageConfirmRequest request); + + AlbumImagesConfirmResponse confirmAlbumImagesUpload( + Long albumId, AlbumImagesConfirmRequest request); } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java index 7ee716bb..ccd98aba 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java @@ -114,7 +114,7 @@ public PresignedUrlResponse createEventCoverImageUploadUrl(ImageUploadRequest re } @Override - public ImageUploadListResponse createAlbumImageUploadUrls( + public AlbumImageUploadResponse createAlbumImageUploadUrls( Long albumId, AlbumImageUploadRequest request) { final Member currentMember = memberUtil.getCurrentMember(); final Album album = getAlbumByIdWithLock(albumId); @@ -130,8 +130,6 @@ public ImageUploadListResponse createAlbumImageUploadUrls( validateAlbumCapacity(album, uploadCapacityMb); validateDistinctHashes(request); - album.increaseCapacity(uploadCapacityMb); - List presignedUrls = request.payloads().stream() .map( @@ -143,42 +141,7 @@ public ImageUploadListResponse createAlbumImageUploadUrls( req.md5Hashes())) .toList(); - List images = - IntStream.range(0, request.payloads().size()) - .mapToObj( - i -> { - AlbumImageUploadRequest.Payload req = request.payloads().get(i); - String presignedUrl = presignedUrls.get(i); - - String objectUrl = - presignedUrl.substring(0, presignedUrl.indexOf("?")); - - return Image.createImage( - album, - currentMember.getId(), - objectUrl, - req.generatedAt() != null - ? req.generatedAt() - : LocalDateTime.now(), - req.capacityMb()); - }) - .toList(); - - imageRepository.bulkInsertImages(images); - - List imageIds = - imageRepository.findImageIdsByUrlsInOrder( - images.stream().map(Image::getUrl).toList()); - - List content = - IntStream.range(0, images.size()) - .mapToObj( - i -> - ImageUploadListResponse.Content.of( - imageIds.get(i), presignedUrls.get(i))) - .toList(); - - return ImageUploadListResponse.of(content, currentMember.getLocalImageDeletion()); + return AlbumImageUploadResponse.of(presignedUrls); } @Override @@ -334,10 +297,59 @@ public void deleteTempAlbumImage(Long tempAlbumId, TempAlbumImageDeleteRequest r } @Override - public void confirmNonAlbumImage(ImageConfirmRequest request) { - if (!s3Util.doesFileExistByUrl(request.imageUrl())) { - throw new CustomException(ImageErrorCode.IMAGE_UPLOAD_FAIL); - } + public void confirmNonAlbumImageUpload(ImageConfirmRequest request) { + validateImageUpload(request.imageUrl()); + + s3Util.updateTagToCompleteByUrl(request.imageUrl()); + } + + @Override + public AlbumImagesConfirmResponse confirmAlbumImagesUpload( + Long albumId, AlbumImagesConfirmRequest request) { + final Member currentMember = memberUtil.getCurrentMember(); + final Album album = getAlbumById(albumId); + + List imageUrls = + request.payloads().stream() + .map(AlbumImagesConfirmRequest.Payload::imageUrl) + .toList(); + + validateImagesUpload(imageUrls); + + s3Util.updateTagsToCompleteByUrls(imageUrls); + + BigDecimal uploadCapacityMb = + request.payloads().stream() + .map(AlbumImagesConfirmRequest.Payload::capacityMb) + .reduce(BigDecimal.ZERO, BigDecimal::add); + album.increaseCapacity(uploadCapacityMb); + + List images = + IntStream.range(0, request.payloads().size()) + .mapToObj( + i -> { + AlbumImagesConfirmRequest.Payload req = + request.payloads().get(i); + String imageUrl = imageUrls.get(i); + + return Image.createImage( + album, + currentMember.getId(), + imageUrl, + req.generatedAt() != null + ? req.generatedAt() + : LocalDateTime.now(), + req.capacityMb()); + }) + .toList(); + + imageRepository.bulkInsertImages(images); + + List imageIds = + imageRepository.findImageIdsByUrlsInOrder( + images.stream().map(Image::getUrl).toList()); + + return AlbumImagesConfirmResponse.of(imageIds, currentMember.getLocalImageDeletion()); } private Album getAlbumById(Long albumId) { @@ -467,4 +479,16 @@ private void validateSubscriptionNotExpired(Album album) { throw new CustomException(AlbumErrorCode.EXPIRED_SUBSCRIPTION); } } + + private void validateImageUpload(String imageUrl) { + if (!s3Util.doesFileExistByUrl(imageUrl)) { + throw new CustomException(ImageErrorCode.IMAGE_UPLOAD_FAIL); + } + } + + private void validateImagesUpload(List imageUrls) { + if (!s3Util.doAllFilesExistByUrls(imageUrls)) { + throw new CustomException(ImageErrorCode.IMAGE_UPLOAD_FAIL); + } + } } diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index d5467fd2..617318c8 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -1772,7 +1772,7 @@ class 앨범_외_이미지_업로드_검증_요청_시 { // given ImageConfirmRequest request = new ImageConfirmRequest("testImageUrl"); - willDoNothing().given(imageService).confirmNonAlbumImage(request); + willDoNothing().given(imageService).confirmNonAlbumImageUpload(request); // when & then ResultActions perform = @@ -1793,7 +1793,7 @@ class 앨범_외_이미지_업로드_검증_요청_시 { willThrow(new CustomException(ImageErrorCode.IMAGE_UPLOAD_FAIL)) .given(imageService) - .confirmNonAlbumImage(request); + .confirmNonAlbumImageUpload(request); // when & then ResultActions perform = diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java index 168927f0..7d2bebc3 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java @@ -1263,7 +1263,7 @@ class 앨범_외_이미지_업로드를_검증할_때 { given(s3Util.doesFileExistByUrl("testImageUrl")).willReturn(true); // when & then - assertDoesNotThrow(() -> imageService.confirmNonAlbumImage(request)); + assertDoesNotThrow(() -> imageService.confirmNonAlbumImageUpload(request)); } @Test @@ -1273,7 +1273,7 @@ class 앨범_외_이미지_업로드를_검증할_때 { given(s3Util.doesFileExistByUrl("testImageUrl")).willReturn(false); // when & then - assertThatThrownBy(() -> imageService.confirmNonAlbumImage(request)) + assertThatThrownBy(() -> imageService.confirmNonAlbumImageUpload(request)) .isInstanceOf(CustomException.class) .hasMessage(ImageErrorCode.IMAGE_UPLOAD_FAIL.getMessage()); } diff --git a/cherrypic-infrastructure/src/main/java/org/cherrypic/s3/S3Util.java b/cherrypic-infrastructure/src/main/java/org/cherrypic/s3/S3Util.java index 0069c560..3b7f4779 100644 --- a/cherrypic-infrastructure/src/main/java/org/cherrypic/s3/S3Util.java +++ b/cherrypic-infrastructure/src/main/java/org/cherrypic/s3/S3Util.java @@ -80,6 +80,12 @@ public void updateTagToCompleteByUrl(String url) { amazonS3.setObjectTagging(request); } + public void updateTagsToCompleteByUrls(List urls) { + for (String url : urls) { + updateTagToCompleteByUrl(url); + } + } + public boolean doesFileExistByUrl(String url) { String bucket = s3Properties.bucket(); String key = extractObjectKey(url); @@ -98,6 +104,17 @@ public boolean doesFileExistByUrl(String url) { } } + public boolean doAllFilesExistByUrls(List urls) { + for (String url : urls) { + if (!doesFileExistByUrl(url)) { + log.warn("File not found or inaccessible: {}", url); + return false; + } + } + + return true; + } + public void deleteAllByUrls(List urls) { if (urls == null || urls.isEmpty()) { log.info("deleteAllByUrls skipped: received null or empty urls"); From f54b6dbc18fd9f0faffcf86bed06d4588f0e5f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Fri, 31 Oct 2025 16:30:28 +0900 Subject: [PATCH 05/16] =?UTF-8?q?test:=20service=20test=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/AlbumImagesConfirmRequest.java | 1 - .../image/controller/ImageControllerTest.java | 92 ++------- .../image/service/ImageServiceTest.java | 180 ++++++++++-------- 3 files changed, 124 insertions(+), 149 deletions(-) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java index 7f859c7f..f97697b6 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java @@ -15,7 +15,6 @@ public record AlbumImagesConfirmRequest( List payloads) { @Schema(name = "AlbumImagesConfirmPayload") public record Payload( - String md5Hashes, @Schema(description = "파일이 찍힌 시간, 정보가 없다면 null을 넣어주세요.") LocalDateTime generatedAt, @NotNull(message = "파일의 용량은 비워둘 수 없습니다.") @Schema(description = "업로드 하는 파일의 용량(MB), 소수점 2자리 까지", example = "0.04") diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index 617318c8..41b4cedd 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -345,22 +345,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ONE), + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash2", - LocalDateTime.now(), - BigDecimal.ONE))); + FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); - ImageUploadListResponse response = - new ImageUploadListResponse( - false, - List.of( - new ImageUploadListResponse.Content(1L, "testPresignedUrl1"), - new ImageUploadListResponse.Content(2L, "testPresignedUrl2"))); + AlbumImageUploadResponse response = + new AlbumImageUploadResponse(List.of("testPresignedUrl1", "testPresignedUrl2")); given(imageService.createAlbumImageUploadUrls(1L, request)).willReturn(response); @@ -374,8 +364,7 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { perform.andExpect(status().isOk()) .andExpect(jsonPath("$.success").value(true)) .andExpect(jsonPath("$.status").value(HttpStatus.OK.value())) - .andExpect(jsonPath("$.data.content").isNotEmpty()) - .andExpect(jsonPath("$.data.localImageDeletion").value(false)); + .andExpect(jsonPath("$.data.urls").isNotEmpty()); } @Test @@ -385,15 +374,9 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ONE), + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash2", - LocalDateTime.now(), - BigDecimal.ONE))); + FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) .willThrow(new CustomException(AlbumErrorCode.ALBUM_NOT_FOUND)); @@ -419,15 +402,9 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ONE), + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash2", - LocalDateTime.now(), - BigDecimal.ONE))); + FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) .willThrow(new CustomException(AlbumErrorCode.NOT_ALBUM_PARTICIPANT)); @@ -453,15 +430,9 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ONE), + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash2", - LocalDateTime.now(), - BigDecimal.ONE))); + FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) .willThrow(new CustomException(AlbumErrorCode.LIMITED_AUTHORITY)); @@ -487,15 +458,9 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ONE), + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash2", - LocalDateTime.now(), - BigDecimal.ONE))); + FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) .willThrow(new CustomException(AlbumErrorCode.EXPIRED_SUBSCRIPTION)); @@ -522,15 +487,9 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ONE), + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash2", - LocalDateTime.now(), - BigDecimal.ONE))); + FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) .willThrow(new CustomException(AlbumErrorCode.ALBUM_CAPACITY_EXCEEDED)); @@ -556,15 +515,9 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash", - LocalDateTime.now(), - BigDecimal.ONE), + FileExtension.JPEG, "testMd5Hash", BigDecimal.ONE), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash", - LocalDateTime.now(), - BigDecimal.ONE))); + FileExtension.JPEG, "testMd5Hash", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) .willThrow(new CustomException(ImageErrorCode.DUPLICATE_HASHES)); @@ -595,7 +548,6 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { new AlbumImageUploadRequest.Payload( FileExtension.from(extension), "testMd5Hash1", - LocalDateTime.now(), BigDecimal.ONE))); // when & then @@ -622,10 +574,7 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash", - LocalDateTime.now(), - null))); + FileExtension.JPEG, "testMd5Hash", null))); // when & then ResultActions perform = @@ -651,10 +600,7 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - md5Hash, - LocalDateTime.now(), - BigDecimal.ONE))); + FileExtension.JPEG, md5Hash, BigDecimal.ONE))); // when & then ResultActions perform = diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java index 7d2bebc3..5dd81567 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.mockito.ArgumentMatchers.*; import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.willDoNothing; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -302,21 +303,15 @@ void setUp() { } @Test - void 유효한_요청이면_이미지를_저장하고_Presigned_URL들을_반환한다() { + void 유효한_요청이면_Presigned_URL들을_반환한다() { // given AlbumImageUploadRequest request = new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ONE), + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash2", - LocalDateTime.now(), - BigDecimal.ONE))); + FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given( s3Util.createPresignedUrl( eq(ImageType.ALBUM_IMAGE), @@ -344,39 +339,23 @@ void setUp() { + "&Content-MD5=testMd5Hash2"); // when - ImageUploadListResponse response = imageService.createAlbumImageUploadUrls(1L, request); + AlbumImageUploadResponse response = + imageService.createAlbumImageUploadUrls(1L, request); // then - assertThat(response.content()) + assertThat(response.urls()) .hasSize(2) .satisfiesExactly( payload1 -> { - assertThat(payload1.imageId()).isEqualTo(1L); - assertThat(payload1.presignedUrl()) + assertThat(payload1) .containsPattern( ".*/local/album-image/1/[\\w\\-]+\\.(jpg|jpeg)\\?.+"); }, payload2 -> { - assertThat(payload2.imageId()).isEqualTo(2L); - assertThat(payload2.presignedUrl()) + assertThat(payload2) .containsPattern( ".*/local/album-image/1/[\\w\\-]+\\.(jpg|jpeg)\\?.+"); }); - assertThat(response.localImageDeletion()).isFalse(); - - List images = imageRepository.findAll(); - assertThat(images) - .hasSize(2) - .allSatisfy( - image -> { - assertThat(image.getAlbum().getId()).isEqualTo(1L); - assertThat(image.getMemberId()).isEqualTo(1L); - assertThat(image.getUrl()) - .containsPattern( - String.format( - "/%s/%s/%d/[\\w\\-]+\\.(jpg|jpeg)", - "local", "album-image", 1)); - }); } @Test @@ -386,15 +365,9 @@ void setUp() { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ZERO), + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash2", - LocalDateTime.now(), - BigDecimal.ZERO))); + FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then assertThatThrownBy(() -> imageService.createAlbumImageUploadUrls(999L, request)) @@ -409,15 +382,9 @@ void setUp() { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ZERO), + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash2", - LocalDateTime.now(), - BigDecimal.ZERO))); + FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then assertThatThrownBy(() -> imageService.createAlbumImageUploadUrls(3L, request)) @@ -432,15 +399,9 @@ void setUp() { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ZERO), + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash2", - LocalDateTime.now(), - BigDecimal.ZERO))); + FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then assertThatThrownBy(() -> imageService.createAlbumImageUploadUrls(2L, request)) @@ -455,15 +416,9 @@ void setUp() { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ZERO), + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash2", - LocalDateTime.now(), - BigDecimal.ZERO))); + FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then assertThatThrownBy(() -> imageService.createAlbumImageUploadUrls(4L, request)) @@ -480,13 +435,9 @@ void setUp() { new AlbumImageUploadRequest.Payload( FileExtension.JPEG, "testMd5Hash1", - LocalDateTime.now(), AlbumType.BASIC.getCapacityMb()), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash2", - LocalDateTime.now(), - BigDecimal.ONE))); + FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then assertThatThrownBy(() -> imageService.createAlbumImageUploadUrls(1L, request)) @@ -501,15 +452,9 @@ void setUp() { new AlbumImageUploadRequest( List.of( new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ZERO), + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO), new AlbumImageUploadRequest.Payload( - FileExtension.JPEG, - "testMd5Hash1", - LocalDateTime.now(), - BigDecimal.ZERO))); + FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO))); // when & then assertThatThrownBy(() -> imageService.createAlbumImageUploadUrls(1L, request)) .isInstanceOf(CustomException.class) @@ -1278,4 +1223,89 @@ class 앨범_외_이미지_업로드를_검증할_때 { .hasMessage(ImageErrorCode.IMAGE_UPLOAD_FAIL.getMessage()); } } + + @Nested + class 앨범_이미지_업로드를_검증할_때 { + + @BeforeEach + void setUp() { + Member member = + Member.createMember( + OauthInfo.createOauthInfo("testOauthId", "testOauthProvider"), + "testNickname", + "testProfileImageUrl"); + memberRepository.save(member); + given(memberUtil.getCurrentMember()).willReturn(member); + + Album album = Album.createAlbum("testTitle1", "testCoverUrl1", AlbumType.BASIC, false); + album.increaseCapacity(BigDecimal.ONE); + albumRepository.save(album); + } + + @Test + void 유효한_요청이면_이미지를_생성한다() { + // given + AlbumImagesConfirmRequest request = + new AlbumImagesConfirmRequest( + List.of( + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, "testImageUrl1"), + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); + + given(s3Util.doAllFilesExistByUrls(List.of("testImageUrl1", "testImageUrl2"))) + .willReturn(true); + willDoNothing() + .given(s3Util) + .updateTagsToCompleteByUrls(List.of("testImageUrl1", "testImageUrl2")); + + // when + AlbumImagesConfirmResponse response = + imageService.confirmAlbumImagesUpload(1L, request); + + // then + Assertions.assertAll( + () -> assertThat(response.localImageDeletion()).isFalse(), + () -> assertThat(response.imageIds()).isEqualTo(List.of(1L, 2L)), + () -> + assertThat(imageRepository.findAllById(List.of(1L, 2L)).size()) + .isEqualTo(2)); + } + + @Test + void 앨범이_존재하지_않는_경우_예외가_발생한다() { + // given + AlbumImagesConfirmRequest request = + new AlbumImagesConfirmRequest( + List.of( + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, "testImageUrl1"), + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); + + // when & then + assertThatThrownBy(() -> imageService.confirmAlbumImagesUpload(999L, request)) + .isInstanceOf(CustomException.class) + .hasMessage(AlbumErrorCode.ALBUM_NOT_FOUND.getMessage()); + } + + @Test + void 모든_이미지를_업로드_성공하지_않았을_경우_예외가_발생한다() { + // given + AlbumImagesConfirmRequest request = + new AlbumImagesConfirmRequest( + List.of( + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, "testImageUrl1"), + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); + given(s3Util.doAllFilesExistByUrls(List.of("testImageUrl1", "testImageUrl2"))) + .willReturn(false); + + // when & then + assertThatThrownBy(() -> imageService.confirmAlbumImagesUpload(1L, request)) + .isInstanceOf(CustomException.class) + .hasMessage(ImageErrorCode.IMAGE_UPLOAD_FAIL.getMessage()); + } + } } From c030027ee6d813d8a70912d9276bbe56bbf4df91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Fri, 31 Oct 2025 16:48:36 +0900 Subject: [PATCH 06/16] =?UTF-8?q?test:=20controller=20test=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/controller/ImageController.java | 2 +- .../request/AlbumImagesConfirmRequest.java | 3 +- .../image/controller/ImageControllerTest.java | 159 ++++++++++++++++++ 3 files changed, 162 insertions(+), 2 deletions(-) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java index 298fcba5..7ac18735 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java @@ -68,7 +68,7 @@ public AlbumImageUploadResponse albumImageUploadUrlsCreate( return imageService.createAlbumImageUploadUrls(albumId, request); } - @PostMapping("/album/{albumId}/confirm-images-upload") + @PostMapping("/albums/{albumId}/confirm-images-upload") @Operation(summary = "앨범 이미지 업로드 검증", description = "앨범 이미지들의 업로드를 검증합니다.") public AlbumImagesConfirmResponse albumImagesUploadConfirm( @PathVariable Long albumId, @Valid @RequestBody AlbumImagesConfirmRequest request) { diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java index f97697b6..62e6761a 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import java.math.BigDecimal; @@ -19,7 +20,7 @@ public record Payload( @NotNull(message = "파일의 용량은 비워둘 수 없습니다.") @Schema(description = "업로드 하는 파일의 용량(MB), 소수점 2자리 까지", example = "0.04") BigDecimal capacityMb, - @NotEmpty(message = "검증하고자 하는 imageUrl은 비워둘 수 없습니다.") + @NotBlank(message = "검증하고자 하는 imageUrl은 비워둘 수 없습니다.") @Valid @Schema(description = "검증 요청 이미지 Url") String imageUrl) {} diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index 41b4cedd..17cc03f4 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -23,6 +23,7 @@ import org.cherrypic.global.pagination.SortParameter; import org.cherrypic.s3.enums.FileExtension; import org.cherrypic.tempalbum.enums.TempAlbumType; +import org.hamcrest.Matchers; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -1777,4 +1778,162 @@ class 앨범_외_이미지_업로드_검증_요청_시 { .andExpect(jsonPath("$.data.message").value("이미지 url을 비워둘 수 없습니다.")); } } + + @Nested + class 앨범_이미지_업로드_요청_시 { + + @Test + void 유효한_요청이면_생성된_이미지_ID와_로컬_이미지_삭제_여부를_반환한다() throws Exception { + // given + AlbumImagesConfirmRequest request = + new AlbumImagesConfirmRequest( + List.of( + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, "testImageUrl1"), + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); + + AlbumImagesConfirmResponse response = + new AlbumImagesConfirmResponse(false, List.of(1L, 2L)); + + given(imageService.confirmAlbumImagesUpload(1L, request)).willReturn(response); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/albums/1/confirm-images-upload") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.status").value(HttpStatus.OK.value())) + .andExpect(jsonPath("$.data.localImageDeletion").value(false)) + .andExpect(jsonPath("$.data.imageIds").value(Matchers.contains(1, 2))); + } + + @Test + void 앨범이_존재하지_않는_경우_예외가_발생한다() throws Exception { + // given + AlbumImagesConfirmRequest request = + new AlbumImagesConfirmRequest( + List.of( + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, "testImageUrl1"), + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); + + given(imageService.confirmAlbumImagesUpload(1L, request)) + .willThrow(new CustomException(AlbumErrorCode.ALBUM_NOT_FOUND)); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/albums/1/confirm-images-upload") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isNotFound()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.NOT_FOUND.value())) + .andExpect(jsonPath("$.data.code").value("ALBUM_NOT_FOUND")) + .andExpect(jsonPath("$.data.message").value("앨범이 존재하지 않습니다.")); + } + + @Test + void 모든_이미지를_업로드_성공하지_않았을_경우_예외가_발생한다() throws Exception { + // given + AlbumImagesConfirmRequest request = + new AlbumImagesConfirmRequest( + List.of( + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, "testImageUrl1"), + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); + + given(imageService.confirmAlbumImagesUpload(1L, request)) + .willThrow(new CustomException(ImageErrorCode.IMAGE_UPLOAD_FAIL)); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/albums/1/confirm-images-upload") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.data.code").value("IMAGE_UPLOAD_FAIL")) + .andExpect(jsonPath("$.data.message").value("이미지가 성공적으로 업로드 되지 못했습니다.")); + } + + @Test + void 검증하고자_하는_이미지들의_정보를_비워두면_예외가_발생한다() throws Exception { + // given + AlbumImagesConfirmRequest request = new AlbumImagesConfirmRequest(List.of()); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/albums/1/confirm-images-upload") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.data.code").value("MethodArgumentNotValidException")) + .andExpect(jsonPath("$.data.message").value("검증하고자 하는 이미지들의 정보들은 비워둘 수 없습니다.")); + } + + @Test + void 업로드_하는_파일의_용량을_비워두면_예외가_발생한다() throws Exception { + // given + AlbumImagesConfirmRequest request = + new AlbumImagesConfirmRequest( + List.of( + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), null, "testImageUrl1"))); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/albums/1/confirm-images-upload") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.data.code").value("MethodArgumentNotValidException")) + .andExpect(jsonPath("$.data.message").value("파일의 용량은 비워둘 수 없습니다.")); + } + + @ParameterizedTest + @NullSource + @EmptySource + @ValueSource(strings = {" "}) + void 검증_요청_이미지_url을_비워두면_예외가_발생한다(String imageUrl) throws Exception { + // given + AlbumImagesConfirmRequest request = + new AlbumImagesConfirmRequest( + List.of( + new AlbumImagesConfirmRequest.Payload( + LocalDateTime.now(), BigDecimal.ONE, imageUrl))); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/albums/1/confirm-images-upload") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.data.code").value("MethodArgumentNotValidException")) + .andExpect(jsonPath("$.data.message").value("검증하고자 하는 imageUrl은 비워둘 수 없습니다.")); + } + } } From d239e2b4257bdad1718ac046a0292c10412987cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Fri, 31 Oct 2025 17:10:56 +0900 Subject: [PATCH 07/16] =?UTF-8?q?feat:=20=EC=9E=84=EC=8B=9C=20=EC=95=A8?= =?UTF-8?q?=EB=B2=94=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EA=B2=80=EC=A6=9D=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/controller/ImageController.java | 10 ++- .../TempAlbumImagesConfirmRequest.java | 25 ++++++ .../response/AlbumImageUploadResponse.java | 2 +- .../TempAlbumImageUploadListResponse.java | 20 ----- .../TempAlbumImageUploadResponse.java | 11 +++ .../TempAlbumImagesConfirmResponse.java | 11 +++ .../domain/image/service/ImageService.java | 5 +- .../image/service/ImageServiceImpl.java | 79 +++++++++++-------- .../image/controller/ImageControllerTest.java | 8 +- .../image/service/ImageServiceTest.java | 2 +- 10 files changed, 111 insertions(+), 62 deletions(-) create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesConfirmRequest.java delete mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadListResponse.java create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadResponse.java create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesConfirmResponse.java diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java index 7ac18735..603bab0a 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java @@ -121,12 +121,20 @@ public ResponseEntity albumImageDelete( @Operation( summary = "임시 앨범 이미지 업로드 Presigned URL들 생성", description = "임시 앨범 이미지 업로드를 위한 Presigned URL들을 생성합니다.") - public TempAlbumImageUploadListResponse tempAlbumImageUploadUrlsCreate( + public TempAlbumImageUploadResponse tempAlbumImageUploadUrlsCreate( @PathVariable Long tempAlbumId, @Valid @RequestBody TempAlbumImageUploadRequest request) { return imageService.createTempAlbumImageUploadUrls(tempAlbumId, request); } + @PostMapping("/temp-albums/{tempAlbumId}/confirm-images-upload") + @Operation(summary = "임시 앨범 이미지 업로드 검증", description = "임시 앨범 이미지들의 업로드를 검증합니다.") + public TempAlbumImagesConfirmResponse tempAlbumImagesUploadConfirm( + @PathVariable Long tempAlbumId, + @Valid @RequestBody TempAlbumImagesConfirmRequest request) { + return imageService.confirmTempAlbumImagesUpload(tempAlbumId, request); + } + @DeleteMapping("temp-albums/{tempAlbumId}/images") @Operation(summary = "임시 앨범 이미지 삭제", description = "임시 앨범의 이미지를 삭제합니다.") public ResponseEntity tempAlbumImageDelete( diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesConfirmRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesConfirmRequest.java new file mode 100644 index 00000000..84fb7175 --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesConfirmRequest.java @@ -0,0 +1,25 @@ +package org.cherrypic.domain.image.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.util.List; + +public record TempAlbumImagesConfirmRequest( + @NotEmpty(message = "검증하고자 하는 임시 앨범 이미지들의 정보들은 비워둘 수 없습니다.") + @Valid + @Schema(description = "검증 요청 리스트") + List payloads) { + @Schema(name = "TempAlbumImagesConfirmPayload") + public record Payload( + @NotNull(message = "파일의 용량은 비워둘 수 없습니다.") + @Schema(description = "업로드 하는 파일의 용량(MB), 소수점 2자리 까지", example = "0.04") + BigDecimal capacityMb, + @NotBlank(message = "검증하고자 하는 tempAlbumImageUrl은 비워둘 수 없습니다.") + @Valid + @Schema(description = "검증 요청 임시 앨범 이미지 Url") + String tempAlbumImageUrl) {} +} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadResponse.java index 2bd44d68..ca73b22f 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadResponse.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadResponse.java @@ -4,7 +4,7 @@ import java.util.List; public record AlbumImageUploadResponse( - @Schema(description = "생성된 presigned url 리스트", example = "1") List urls) { + @Schema(description = "생성된 presigned url 리스트", example = "[1,2,3,4]") List urls) { public static AlbumImageUploadResponse of(List urls) { return new AlbumImageUploadResponse(urls); } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadListResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadListResponse.java deleted file mode 100644 index dea92cc6..00000000 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadListResponse.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.cherrypic.domain.image.dto.response; - -import io.swagger.v3.oas.annotations.media.Schema; -import java.util.List; - -public record TempAlbumImageUploadListResponse( - @Schema(description = "업로드된 임시 앨범 이미지들의 정보 리스트") List content) { - public static TempAlbumImageUploadListResponse of(List content) { - return new TempAlbumImageUploadListResponse(content); - } - - @Schema(name = "TempAlbumImageUploadResponseContent") - public record Content( - @Schema(description = "생성된 임시 앨범 이미지의 ID") Long tempAlbumImageId, - @Schema(description = "생성된 Presigned Url") String presignedUrl) { - public static Content of(Long imageId, String presignedUrl) { - return new Content(imageId, presignedUrl); - } - } -} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadResponse.java new file mode 100644 index 00000000..b1c28028 --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadResponse.java @@ -0,0 +1,11 @@ +package org.cherrypic.domain.image.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; + +public record TempAlbumImageUploadResponse( + @Schema(description = "생성된 presigned url 리스트", example = "[1,2,3,4]") List urls) { + public static TempAlbumImageUploadResponse of(List urls) { + return new TempAlbumImageUploadResponse(urls); + } +} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesConfirmResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesConfirmResponse.java new file mode 100644 index 00000000..fa3578bc --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesConfirmResponse.java @@ -0,0 +1,11 @@ +package org.cherrypic.domain.image.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; + +public record TempAlbumImagesConfirmResponse( + @Schema(description = "생성된 임시 앨범 이미지들의 ID 리스트") List tempAlbumImagesId) { + public static TempAlbumImagesConfirmResponse of(List tempAlbumImagesId) { + return new TempAlbumImagesConfirmResponse(tempAlbumImagesId); + } +} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java index 977b4cd9..72d172a2 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java @@ -32,7 +32,7 @@ SliceResponse getEventImages( void deleteAlbumImage(Long albumId, AlbumImageDeleteRequest request); - TempAlbumImageUploadListResponse createTempAlbumImageUploadUrls( + TempAlbumImageUploadResponse createTempAlbumImageUploadUrls( Long tempAlbumId, TempAlbumImageUploadRequest request); void deleteTempAlbumImage(Long tempAlbumId, TempAlbumImageDeleteRequest request); @@ -41,4 +41,7 @@ TempAlbumImageUploadListResponse createTempAlbumImageUploadUrls( AlbumImagesConfirmResponse confirmAlbumImagesUpload( Long albumId, AlbumImagesConfirmRequest request); + + TempAlbumImagesConfirmResponse confirmTempAlbumImagesUpload( + Long tempAlbumId, TempAlbumImagesConfirmRequest request); } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java index ccd98aba..50b58b62 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java @@ -207,7 +207,7 @@ public void deleteAlbumImage(Long albumId, AlbumImageDeleteRequest request) { @Override @Transactional - public TempAlbumImageUploadListResponse createTempAlbumImageUploadUrls( + public TempAlbumImageUploadResponse createTempAlbumImageUploadUrls( Long tempAlbumId, TempAlbumImageUploadRequest request) { final Member currentMember = memberUtil.getCurrentMember(); final TempAlbum tempAlbum = getTempAlbumById(tempAlbumId); @@ -222,8 +222,6 @@ public TempAlbumImageUploadListResponse createTempAlbumImageUploadUrls( validateTempAlbumCapacity(tempAlbum, uploadCapacityMb); validateDistinctHashes(request); - tempAlbum.increaseCapacity(uploadCapacityMb); - List presignedUrls = request.payloads().stream() .map( @@ -235,37 +233,7 @@ public TempAlbumImageUploadListResponse createTempAlbumImageUploadUrls( req.md5Hashes())) .toList(); - List tempAlbumImages = - IntStream.range(0, request.payloads().size()) - .mapToObj( - i -> { - TempAlbumImageUploadRequest.Payload req = - request.payloads().get(i); - String presignedUrl = presignedUrls.get(i); - - String objectUrl = - presignedUrl.substring(0, presignedUrl.indexOf("?")); - - return TempAlbumImage.createTempAlbumImage( - tempAlbum, objectUrl, req.capacityMb()); - }) - .toList(); - - imageRepository.bulkInsertTempAlbumImages(tempAlbumImages); - - List tempAlbumImageIds = - imageRepository.findTempImageIdsByUrlsInOrder( - tempAlbumImages.stream().map(TempAlbumImage::getUrl).toList()); - - List content = - IntStream.range(0, tempAlbumImageIds.size()) - .mapToObj( - i -> - TempAlbumImageUploadListResponse.Content.of( - tempAlbumImageIds.get(i), presignedUrls.get(i))) - .toList(); - - return TempAlbumImageUploadListResponse.of(content); + return TempAlbumImageUploadResponse.of(presignedUrls); } @Override @@ -352,6 +320,49 @@ public AlbumImagesConfirmResponse confirmAlbumImagesUpload( return AlbumImagesConfirmResponse.of(imageIds, currentMember.getLocalImageDeletion()); } + @Override + public TempAlbumImagesConfirmResponse confirmTempAlbumImagesUpload( + Long tempAlbumId, TempAlbumImagesConfirmRequest request) { + final TempAlbum tempAlbum = getTempAlbumById(tempAlbumId); + + List imageUrls = + request.payloads().stream() + .map(TempAlbumImagesConfirmRequest.Payload::tempAlbumImageUrl) + .toList(); + + validateImagesUpload(imageUrls); + + s3Util.updateTagsToCompleteByUrls(imageUrls); + + BigDecimal uploadCapacityMb = + request.payloads().stream() + .map(TempAlbumImagesConfirmRequest.Payload::capacityMb) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + tempAlbum.increaseCapacity(uploadCapacityMb); + + List tempAlbumImages = + IntStream.range(0, request.payloads().size()) + .mapToObj( + i -> { + TempAlbumImagesConfirmRequest.Payload req = + request.payloads().get(i); + String imageUrl = imageUrls.get(i); + + return TempAlbumImage.createTempAlbumImage( + tempAlbum, imageUrl, req.capacityMb()); + }) + .toList(); + + imageRepository.bulkInsertTempAlbumImages(tempAlbumImages); + + List tempAlbumImageIds = + imageRepository.findTempImageIdsByUrlsInOrder( + tempAlbumImages.stream().map(TempAlbumImage::getUrl).toList()); + + return TempAlbumImagesConfirmResponse.of(tempAlbumImageIds); + } + private Album getAlbumById(Long albumId) { return albumRepository .findById(albumId) diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index 17cc03f4..e88f1ecf 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -1348,12 +1348,12 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { "testMd5Hash2", new BigDecimal("0.3")))); - TempAlbumImageUploadListResponse response = - new TempAlbumImageUploadListResponse( + TempAlbumImageUploadResponse response = + new TempAlbumImageUploadResponse( List.of( - new TempAlbumImageUploadListResponse.Content( + new TempAlbumImageUploadResponse.Content( 1L, "testPresignedUrl1"), - new TempAlbumImageUploadListResponse.Content( + new TempAlbumImageUploadResponse.Content( 2L, "testPresignedUrl2"))); given(imageService.createTempAlbumImageUploadUrls(1L, request)).willReturn(response); diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java index 5dd81567..ac6579d4 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java @@ -995,7 +995,7 @@ void setUp() { + "&Content-MD5=testMd5Hash2"); // when - TempAlbumImageUploadListResponse response = + TempAlbumImageUploadResponse response = imageService.createTempAlbumImageUploadUrls(1L, request); // then From 3f86d188c397398a7910c07b0f5502668462b2e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Fri, 31 Oct 2025 17:21:01 +0900 Subject: [PATCH 08/16] =?UTF-8?q?test:=20service=20test=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/controller/ImageControllerTest.java | 6 +- .../image/service/ImageServiceTest.java | 107 ++++++++++++++---- 2 files changed, 89 insertions(+), 24 deletions(-) diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index e88f1ecf..a451e8e7 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -1350,11 +1350,7 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { TempAlbumImageUploadResponse response = new TempAlbumImageUploadResponse( - List.of( - new TempAlbumImageUploadResponse.Content( - 1L, "testPresignedUrl1"), - new TempAlbumImageUploadResponse.Content( - 2L, "testPresignedUrl2"))); + List.of("testPresignedUrl1", "testPresignedUrl2")); given(imageService.createTempAlbumImageUploadUrls(1L, request)).willReturn(response); diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java index ac6579d4..7fa1264f 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java @@ -955,7 +955,7 @@ void setUp() { } @Test - void 유효한_요청이면_임시_앨범_이미지를_저장하고_Presigned_URL들을_반환한다() { + void 유효한_요청이면_Presigned_URL들을_반환한다() { // given TempAlbumImageUploadRequest request = new TempAlbumImageUploadRequest( @@ -999,34 +999,19 @@ void setUp() { imageService.createTempAlbumImageUploadUrls(1L, request); // then - assertThat(response.content()) + assertThat(response.urls()) .hasSize(2) .satisfiesExactly( payload1 -> { - assertThat(payload1.tempAlbumImageId()).isEqualTo(1L); - assertThat(payload1.presignedUrl()) + assertThat(payload1) .containsPattern( ".*/local/temp-album-image/1/[\\w\\-]+\\.(jpg|jpeg)\\?.+"); }, payload2 -> { - assertThat(payload2.tempAlbumImageId()).isEqualTo(2L); - assertThat(payload2.presignedUrl()) + assertThat(payload2) .containsPattern( ".*/local/temp-album-image/1/[\\w\\-]+\\.(jpg|jpeg)\\?.+"); }); - - List tempAlbumImages = tempAlbumImageRepository.findAll(); - assertThat(tempAlbumImages) - .hasSize(2) - .allSatisfy( - tempAlbumImage -> { - assertThat(tempAlbumImage.getTempAlbum().getId()).isEqualTo(1L); - assertThat(tempAlbumImage.getUrl()) - .containsPattern( - String.format( - "/%s/%s/%d/[\\w\\-]+\\.(jpg|jpeg)", - "local", "temp-album-image", 1)); - }); } @Test @@ -1308,4 +1293,88 @@ void setUp() { .hasMessage(ImageErrorCode.IMAGE_UPLOAD_FAIL.getMessage()); } } + + @Nested + class 임시_앨범_이미지_업로드를_검증할_때 { + + @BeforeEach + void setUp() { + Member member = + Member.createMember( + OauthInfo.createOauthInfo("testOauthId", "testOauthProvider"), + "testNickname1", + "testProfileImageUrl1"); + memberRepository.save(member); + given(memberUtil.getCurrentMember()).willReturn(member); + + TempAlbum tempAlbum = TempAlbum.createTempAlbum(member, "testTitle1"); + tempAlbumRepository.save(tempAlbum); + } + + @Test + void 유효한_요청이면_임시_앨범_이미지를_생성한다() { + // given + TempAlbumImagesConfirmRequest request = + new TempAlbumImagesConfirmRequest( + List.of( + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, "testImageUrl1"), + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, "testImageUrl2"))); + + given(s3Util.doAllFilesExistByUrls(List.of("testImageUrl1", "testImageUrl2"))) + .willReturn(true); + willDoNothing() + .given(s3Util) + .updateTagsToCompleteByUrls(List.of("testImageUrl1", "testImageUrl2")); + + // when + TempAlbumImagesConfirmResponse response = + imageService.confirmTempAlbumImagesUpload(1L, request); + + // then + Assertions.assertAll( + () -> assertThat(response.tempAlbumImagesId()).isEqualTo(List.of(1L, 2L)), + () -> + assertThat(tempAlbumImageRepository.findAllById(List.of(1L, 2L)).size()) + .isEqualTo(2)); + } + + @Test + void 임시_앨범이_존재하지_않는_경우_예외가_발생한다() { + // given + TempAlbumImagesConfirmRequest request = + new TempAlbumImagesConfirmRequest( + List.of( + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, "testImageUrl1"), + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, "testImageUrl2"))); + + // when & then + assertThatThrownBy(() -> imageService.confirmTempAlbumImagesUpload(999L, request)) + .isInstanceOf(CustomException.class) + .hasMessage(TempAlbumErrorCode.TEMP_ALBUM_NOT_FOUND.getMessage()); + } + + @Test + void 모든_이미지를_업로드_성공하지_않았을_경우_예외가_발생한다() { + // given + TempAlbumImagesConfirmRequest request = + new TempAlbumImagesConfirmRequest( + List.of( + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, "testImageUrl1"), + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, "testImageUrl2"))); + + given(s3Util.doAllFilesExistByUrls(List.of("testImageUrl1", "testImageUrl2"))) + .willReturn(false); + + // when & then + assertThatThrownBy(() -> imageService.confirmTempAlbumImagesUpload(1L, request)) + .isInstanceOf(CustomException.class) + .hasMessage(ImageErrorCode.IMAGE_UPLOAD_FAIL.getMessage()); + } + } } From 24554ca3f06efcbbcdf7ab48719e692217ea8171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Fri, 31 Oct 2025 17:29:11 +0900 Subject: [PATCH 09/16] =?UTF-8?q?test:=20controller=20test=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TempAlbumImagesConfirmResponse.java | 6 +- .../image/controller/ImageControllerTest.java | 161 ++++++++++++++++++ .../image/service/ImageServiceTest.java | 2 +- 3 files changed, 165 insertions(+), 4 deletions(-) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesConfirmResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesConfirmResponse.java index fa3578bc..fc96aa87 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesConfirmResponse.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesConfirmResponse.java @@ -4,8 +4,8 @@ import java.util.List; public record TempAlbumImagesConfirmResponse( - @Schema(description = "생성된 임시 앨범 이미지들의 ID 리스트") List tempAlbumImagesId) { - public static TempAlbumImagesConfirmResponse of(List tempAlbumImagesId) { - return new TempAlbumImagesConfirmResponse(tempAlbumImagesId); + @Schema(description = "생성된 임시 앨범 이미지들의 ID 리스트") List tempAlbumImageIds) { + public static TempAlbumImagesConfirmResponse of(List tempAlbumImageIds) { + return new TempAlbumImagesConfirmResponse(tempAlbumImageIds); } } diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index a451e8e7..4cb1ead0 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -1932,4 +1932,165 @@ class 앨범_이미지_업로드_요청_시 { .andExpect(jsonPath("$.data.message").value("검증하고자 하는 imageUrl은 비워둘 수 없습니다.")); } } + + @Nested + class 임시_앨범_이미지_업로드_요청_시 { + + @Test + void 유효한_요청이면_생성된_임시_앨범_이미지_ID들을_반환한다() throws Exception { + // given + TempAlbumImagesConfirmRequest request = + new TempAlbumImagesConfirmRequest( + List.of( + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, "testImageUrl1"), + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, "testImageUrl2"))); + + TempAlbumImagesConfirmResponse response = + new TempAlbumImagesConfirmResponse(List.of(1L, 2L)); + + given(imageService.confirmTempAlbumImagesUpload(1L, request)).willReturn(response); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/temp-albums/1/confirm-images-upload") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.status").value(HttpStatus.OK.value())) + .andExpect(jsonPath("$.data.tempAlbumImageIds").value(Matchers.contains(1, 2))); + } + + @Test + void 임시_앨범이_존재하지_않는_경우_예외가_발생한다() throws Exception { + // given + TempAlbumImagesConfirmRequest request = + new TempAlbumImagesConfirmRequest( + List.of( + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, "testImageUrl1"), + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, "testImageUrl2"))); + + given(imageService.confirmTempAlbumImagesUpload(1L, request)) + .willThrow(new CustomException(TempAlbumErrorCode.TEMP_ALBUM_NOT_FOUND)); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/temp-albums/1/confirm-images-upload") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isNotFound()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.NOT_FOUND.value())) + .andExpect(jsonPath("$.data.code").value("TEMP_ALBUM_NOT_FOUND")) + .andExpect(jsonPath("$.data.message").value("임시 앨범이 존재하지 않습니다.")); + } + + @Test + void 모든_이미지를_업로드_성공하지_않았을_경우_예외가_발생한다() throws Exception { + // given + TempAlbumImagesConfirmRequest request = + new TempAlbumImagesConfirmRequest( + List.of( + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, "testImageUrl1"), + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, "testImageUrl2"))); + + given(imageService.confirmTempAlbumImagesUpload(1L, request)) + .willThrow(new CustomException(ImageErrorCode.IMAGE_UPLOAD_FAIL)); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/temp-albums/1/confirm-images-upload") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.data.code").value("IMAGE_UPLOAD_FAIL")) + .andExpect(jsonPath("$.data.message").value("이미지가 성공적으로 업로드 되지 못했습니다.")); + } + + @Test + void 검증하고자_하는_이미지들의_정보를_비워두면_예외가_발생한다() throws Exception { + // given + TempAlbumImagesConfirmRequest request = new TempAlbumImagesConfirmRequest(List.of()); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/temp-albums/1/confirm-images-upload") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.data.code").value("MethodArgumentNotValidException")) + .andExpect( + jsonPath("$.data.message") + .value("검증하고자 하는 임시 앨범 이미지들의 정보들은 비워둘 수 없습니다.")); + } + + @Test + void 업로드_하는_파일의_용량을_비워두면_예외가_발생한다() throws Exception { + // given + TempAlbumImagesConfirmRequest request = + new TempAlbumImagesConfirmRequest( + List.of( + new TempAlbumImagesConfirmRequest.Payload( + null, "testImageUrl1"))); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/temp-albums/1/confirm-images-upload") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.data.code").value("MethodArgumentNotValidException")) + .andExpect(jsonPath("$.data.message").value("파일의 용량은 비워둘 수 없습니다.")); + } + + @ParameterizedTest + @NullSource + @EmptySource + @ValueSource(strings = {" "}) + void 검증_요청_이미지_url을_비워두면_예외가_발생한다(String imageUrl) throws Exception { + // given + TempAlbumImagesConfirmRequest request = + new TempAlbumImagesConfirmRequest( + List.of( + new TempAlbumImagesConfirmRequest.Payload( + BigDecimal.ONE, imageUrl))); + + // when & then + ResultActions perform = + mockMvc.perform( + post("/temp-albums/1/confirm-images-upload") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + perform.andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.data.code").value("MethodArgumentNotValidException")) + .andExpect( + jsonPath("$.data.message") + .value("검증하고자 하는 tempAlbumImageUrl은 비워둘 수 없습니다.")); + } + } } diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java index 7fa1264f..2526c471 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java @@ -1334,7 +1334,7 @@ void setUp() { // then Assertions.assertAll( - () -> assertThat(response.tempAlbumImagesId()).isEqualTo(List.of(1L, 2L)), + () -> assertThat(response.tempAlbumImageIds()).isEqualTo(List.of(1L, 2L)), () -> assertThat(tempAlbumImageRepository.findAllById(List.of(1L, 2L)).size()) .isEqualTo(2)); From 78d393b4c7ffe77045396999afe6b5e74d894d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Fri, 31 Oct 2025 17:32:24 +0900 Subject: [PATCH 10/16] =?UTF-8?q?fix:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/cherrypic/image/controller/ImageControllerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index 4cb1ead0..45cad173 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -1364,7 +1364,7 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { perform.andExpect(status().isOk()) .andExpect(jsonPath("$.success").value(true)) .andExpect(jsonPath("$.status").value(HttpStatus.OK.value())) - .andExpect(jsonPath("$.data.content").isNotEmpty()); + .andExpect(jsonPath("$.data.urls").isNotEmpty()); } @Test From 87c42f812c30d6480f5768b7a61b1dcbfad9768c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Sat, 1 Nov 2025 15:36:35 +0900 Subject: [PATCH 11/16] =?UTF-8?q?refactor:=20=EB=AA=85=EB=AA=85=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/controller/ImageController.java | 60 +-- ...t.java => AlbumImageUploadUrlRequest.java} | 2 +- ... => AlbumImagesUploadCompleteRequest.java} | 4 +- ...t.java => ImageUploadCompleteRequest.java} | 2 +- ...equest.java => ImageUploadUrlRequest.java} | 2 +- ...va => TempAlbumImageUploadUrlRequest.java} | 2 +- ...TempAlbumImagesUploadCompleteRequest.java} | 4 +- ....java => AlbumImageUploadUrlResponse.java} | 6 +- ...=> AlbumImagesUploadCompleteResponse.java} | 7 +- .../dto/response/ImageUploadUrlResponse.java | 9 + .../dto/response/PresignedUrlResponse.java | 9 - ...a => TempAlbumImageUploadUrlResponse.java} | 6 +- ...empAlbumImagesUploadCompleteResponse.java} | 6 +- .../domain/image/service/ImageService.java | 24 +- .../image/service/ImageServiceImpl.java | 63 +-- .../image/controller/ImageControllerTest.java | 365 +++++++++--------- .../image/service/ImageServiceTest.java | 197 +++++----- 17 files changed, 396 insertions(+), 372 deletions(-) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/{AlbumImageUploadRequest.java => AlbumImageUploadUrlRequest.java} (97%) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/{AlbumImagesConfirmRequest.java => AlbumImagesUploadCompleteRequest.java} (92%) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/{ImageConfirmRequest.java => ImageUploadCompleteRequest.java} (89%) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/{ImageUploadRequest.java => ImageUploadUrlRequest.java} (95%) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/{TempAlbumImageUploadRequest.java => TempAlbumImageUploadUrlRequest.java} (97%) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/{TempAlbumImagesConfirmRequest.java => TempAlbumImagesUploadCompleteRequest.java} (91%) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/{AlbumImageUploadResponse.java => AlbumImageUploadUrlResponse.java} (59%) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/{AlbumImagesConfirmResponse.java => AlbumImagesUploadCompleteResponse.java} (56%) create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImageUploadUrlResponse.java delete mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/PresignedUrlResponse.java rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/{TempAlbumImageUploadResponse.java => TempAlbumImageUploadUrlResponse.java} (57%) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/{TempAlbumImagesConfirmResponse.java => TempAlbumImagesUploadCompleteResponse.java} (53%) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java index 603bab0a..af82262f 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java @@ -12,6 +12,7 @@ import org.cherrypic.global.pagination.SliceResponse; import org.cherrypic.global.pagination.SortDirection; import org.cherrypic.global.pagination.SortParameter; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -28,8 +29,8 @@ public class ImageController { @Operation( summary = "회원 프로필 이미지 Presigned URL 생성", description = "회원 프로필 이미지 업로드를 위한 Presigned URL을 생성합니다.") - public PresignedUrlResponse memberProfileImageUploadUrlCreate( - @Valid @RequestBody ImageUploadRequest request) { + public ImageUploadUrlResponse memberProfileImageUploadUrlCreate( + @Valid @RequestBody ImageUploadUrlRequest request) { return imageService.createMemberProfileImageUploadUrl(request); } @@ -37,8 +38,8 @@ public PresignedUrlResponse memberProfileImageUploadUrlCreate( @Operation( summary = "앨범 커버 이미지 Presigned URL 생성", description = "앨범 커버 이미지 업로드를 위한 Presigned URL을 생성합니다.") - public PresignedUrlResponse albumCoverImageUploadUrlCreate( - @Valid @RequestBody ImageUploadRequest request) { + public ImageUploadUrlResponse albumCoverImageUploadUrlCreate( + @Valid @RequestBody ImageUploadUrlRequest request) { return imageService.createAlbumCoverImageUploadUrl(request); } @@ -46,33 +47,36 @@ public PresignedUrlResponse albumCoverImageUploadUrlCreate( @Operation( summary = "이벤트 커버 이미지 Presigned URL 생성", description = "이벤트 커버 이미지 업로드를 위한 Presigned URL을 생성합니다.") - public PresignedUrlResponse eventCoverImageUploadUrlCreate( - @Valid @RequestBody ImageUploadRequest request) { + public ImageUploadUrlResponse eventCoverImageUploadUrlCreate( + @Valid @RequestBody ImageUploadUrlRequest request) { return imageService.createEventCoverImageUploadUrl(request); } - @PostMapping("/image/confirm-non-album") - @Operation(summary = "앨범 사진 외 이미지 업로드 검증", description = "프로필, 커버 사진 등의 이미지 업로드를 검증합니다.") - public ResponseEntity nonAlbumImageUploadConfirm( - @Valid @RequestBody ImageConfirmRequest request) { - imageService.confirmNonAlbumImageUpload(request); + @PostMapping("/image/upload-complete") + @Operation(summary = "앨범 사진 외 이미지 업로드 완료", description = "프로필, 커버 사진 등의 이미지 업로드를 완료합니다.") + public ResponseEntity nonAlbumImageUploadComplete( + @Valid @RequestBody ImageUploadCompleteRequest request) { + imageService.completeNonAlbumImageUpload(request); return ResponseEntity.noContent().build(); } - @PostMapping("/albums/{albumId}/images") + @PostMapping("/albums/{albumId}/upload-url") @Operation( summary = "앨범 이미지 업로드 Presigned URL들 생성", description = "앨범 이미지 업로드를 위한 Presigned URL들을 생성합니다.") - public AlbumImageUploadResponse albumImageUploadUrlsCreate( - @PathVariable Long albumId, @Valid @RequestBody AlbumImageUploadRequest request) { + public AlbumImageUploadUrlResponse albumImageUploadUrlsCreate( + @PathVariable Long albumId, @Valid @RequestBody AlbumImageUploadUrlRequest request) { return imageService.createAlbumImageUploadUrls(albumId, request); } - @PostMapping("/albums/{albumId}/confirm-images-upload") - @Operation(summary = "앨범 이미지 업로드 검증", description = "앨범 이미지들의 업로드를 검증합니다.") - public AlbumImagesConfirmResponse albumImagesUploadConfirm( - @PathVariable Long albumId, @Valid @RequestBody AlbumImagesConfirmRequest request) { - return imageService.confirmAlbumImagesUpload(albumId, request); + @PostMapping("/albums/{albumId}/upload-complete") + @Operation(summary = "앨범 이미지 업로드 완료", description = "앨범 이미지들의 업로드를 완료합니다.") + public ResponseEntity albumImagesUploadComplete( + @PathVariable Long albumId, + @Valid @RequestBody AlbumImagesUploadCompleteRequest request) { + AlbumImagesUploadCompleteResponse response = + imageService.completeAlbumImagesUpload(albumId, request); + return ResponseEntity.status(HttpStatus.CREATED).body(response); } @GetMapping("/albums/{albumId}/images") @@ -117,22 +121,24 @@ public ResponseEntity albumImageDelete( return ResponseEntity.noContent().build(); } - @PostMapping("temp-albums/{tempAlbumId}/images") + @PostMapping("temp-albums/{tempAlbumId}/upload-url") @Operation( summary = "임시 앨범 이미지 업로드 Presigned URL들 생성", description = "임시 앨범 이미지 업로드를 위한 Presigned URL들을 생성합니다.") - public TempAlbumImageUploadResponse tempAlbumImageUploadUrlsCreate( + public TempAlbumImageUploadUrlResponse tempAlbumImageUploadUrlsCreate( @PathVariable Long tempAlbumId, - @Valid @RequestBody TempAlbumImageUploadRequest request) { + @Valid @RequestBody TempAlbumImageUploadUrlRequest request) { return imageService.createTempAlbumImageUploadUrls(tempAlbumId, request); } - @PostMapping("/temp-albums/{tempAlbumId}/confirm-images-upload") - @Operation(summary = "임시 앨범 이미지 업로드 검증", description = "임시 앨범 이미지들의 업로드를 검증합니다.") - public TempAlbumImagesConfirmResponse tempAlbumImagesUploadConfirm( + @PostMapping("/temp-albums/{tempAlbumId}/upload-complete") + @Operation(summary = "임시 앨범 이미지 업로드 완료", description = "임시 앨범 이미지들의 업로드를 완료합니다.") + public ResponseEntity tempAlbumImagesUploadComplete( @PathVariable Long tempAlbumId, - @Valid @RequestBody TempAlbumImagesConfirmRequest request) { - return imageService.confirmTempAlbumImagesUpload(tempAlbumId, request); + @Valid @RequestBody TempAlbumImagesUploadCompleteRequest request) { + TempAlbumImagesUploadCompleteResponse response = + imageService.completeTempAlbumImagesUpload(tempAlbumId, request); + return ResponseEntity.status(HttpStatus.CREATED).body(response); } @DeleteMapping("temp-albums/{tempAlbumId}/images") diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadUrlRequest.java similarity index 97% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadRequest.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadUrlRequest.java index deac84a4..05bfa80f 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadUrlRequest.java @@ -10,7 +10,7 @@ import org.cherrypic.global.annotation.Enum; import org.cherrypic.s3.enums.FileExtension; -public record AlbumImageUploadRequest( +public record AlbumImageUploadUrlRequest( @NotEmpty(message = "업로드할 피일들의 정보는 비워둘 수 없습니다.") @Valid @Schema(description = "업로드 요청 리스트") List payloads) { @Schema(name = "AlbumImageUploadRequestPayload") diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesUploadCompleteRequest.java similarity index 92% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesUploadCompleteRequest.java index 62e6761a..92b34c99 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesConfirmRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesUploadCompleteRequest.java @@ -9,12 +9,12 @@ import java.time.LocalDateTime; import java.util.List; -public record AlbumImagesConfirmRequest( +public record AlbumImagesUploadCompleteRequest( @NotEmpty(message = "검증하고자 하는 이미지들의 정보들은 비워둘 수 없습니다.") @Valid @Schema(description = "검증 요청 리스트") List payloads) { - @Schema(name = "AlbumImagesConfirmPayload") + @Schema(name = "AlbumImagesUploadCompletePayload") public record Payload( @Schema(description = "파일이 찍힌 시간, 정보가 없다면 null을 넣어주세요.") LocalDateTime generatedAt, @NotNull(message = "파일의 용량은 비워둘 수 없습니다.") diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageConfirmRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadCompleteRequest.java similarity index 89% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageConfirmRequest.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadCompleteRequest.java index 3a503212..12f1d307 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageConfirmRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadCompleteRequest.java @@ -3,7 +3,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; -public record ImageConfirmRequest( +public record ImageUploadCompleteRequest( @NotBlank(message = "이미지 url을 비워둘 수 없습니다.") @Schema(description = "검증하고자 하는 이미지 url", example = "https://example.jpg") String imageUrl) {} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadUrlRequest.java similarity index 95% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadRequest.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadUrlRequest.java index 0d5fda12..157cbf30 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadUrlRequest.java @@ -5,7 +5,7 @@ import org.cherrypic.global.annotation.Enum; import org.cherrypic.s3.enums.FileExtension; -public record ImageUploadRequest( +public record ImageUploadUrlRequest( @Enum(message = "이미지 파일의 확장자는 비워둘 수 없으며, PNG, JPG, JPEG, WEBP, HEIC, HEIF만 지원됩니다.") @Schema(description = "이미지 파일의 확장자", defaultValue = "JPEG") FileExtension fileExtension, diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImageUploadRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImageUploadUrlRequest.java similarity index 97% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImageUploadRequest.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImageUploadUrlRequest.java index 0bf06e49..7c43f618 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImageUploadRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImageUploadUrlRequest.java @@ -10,7 +10,7 @@ import org.cherrypic.global.annotation.Enum; import org.cherrypic.s3.enums.FileExtension; -public record TempAlbumImageUploadRequest( +public record TempAlbumImageUploadUrlRequest( @NotEmpty(message = "업로드할 피일들의 정보는 비워둘 수 없습니다.") @Valid @Schema(description = "업로드 요청 리스트") List payloads) { @Schema(name = "TempAlbumImageUploadRequestPayload") diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesConfirmRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesUploadCompleteRequest.java similarity index 91% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesConfirmRequest.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesUploadCompleteRequest.java index 84fb7175..4d4999a4 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesConfirmRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesUploadCompleteRequest.java @@ -8,12 +8,12 @@ import java.math.BigDecimal; import java.util.List; -public record TempAlbumImagesConfirmRequest( +public record TempAlbumImagesUploadCompleteRequest( @NotEmpty(message = "검증하고자 하는 임시 앨범 이미지들의 정보들은 비워둘 수 없습니다.") @Valid @Schema(description = "검증 요청 리스트") List payloads) { - @Schema(name = "TempAlbumImagesConfirmPayload") + @Schema(name = "TempAlbumImagesUploadCompletePayload") public record Payload( @NotNull(message = "파일의 용량은 비워둘 수 없습니다.") @Schema(description = "업로드 하는 파일의 용량(MB), 소수점 2자리 까지", example = "0.04") diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadUrlResponse.java similarity index 59% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadResponse.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadUrlResponse.java index ca73b22f..cfb2fff5 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadResponse.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadUrlResponse.java @@ -3,9 +3,9 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; -public record AlbumImageUploadResponse( +public record AlbumImageUploadUrlResponse( @Schema(description = "생성된 presigned url 리스트", example = "[1,2,3,4]") List urls) { - public static AlbumImageUploadResponse of(List urls) { - return new AlbumImageUploadResponse(urls); + public static AlbumImageUploadUrlResponse of(List urls) { + return new AlbumImageUploadUrlResponse(urls); } } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesConfirmResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadCompleteResponse.java similarity index 56% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesConfirmResponse.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadCompleteResponse.java index cb6c40d9..2a5f33ff 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesConfirmResponse.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadCompleteResponse.java @@ -3,10 +3,11 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; -public record AlbumImagesConfirmResponse( +public record AlbumImagesUploadCompleteResponse( @Schema(description = "로컬 사진 삭제 허용 여부") Boolean localImageDeletion, @Schema(description = "생성된 이미지들의 ID 리스트") List imageIds) { - public static AlbumImagesConfirmResponse of(List imageIds, Boolean localImageDeletion) { - return new AlbumImagesConfirmResponse(localImageDeletion, imageIds); + public static AlbumImagesUploadCompleteResponse of( + List imageIds, Boolean localImageDeletion) { + return new AlbumImagesUploadCompleteResponse(localImageDeletion, imageIds); } } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImageUploadUrlResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImageUploadUrlResponse.java new file mode 100644 index 00000000..c84516c1 --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImageUploadUrlResponse.java @@ -0,0 +1,9 @@ +package org.cherrypic.domain.image.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; + +public record ImageUploadUrlResponse(@Schema(description = "Presigned URL") String presignedUrl) { + public static ImageUploadUrlResponse of(String presignedUrl) { + return new ImageUploadUrlResponse(presignedUrl); + } +} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/PresignedUrlResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/PresignedUrlResponse.java deleted file mode 100644 index 2ae4a804..00000000 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/PresignedUrlResponse.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.cherrypic.domain.image.dto.response; - -import io.swagger.v3.oas.annotations.media.Schema; - -public record PresignedUrlResponse(@Schema(description = "Presigned URL") String presignedUrl) { - public static PresignedUrlResponse of(String presignedUrl) { - return new PresignedUrlResponse(presignedUrl); - } -} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadUrlResponse.java similarity index 57% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadResponse.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadUrlResponse.java index b1c28028..c19279fb 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadResponse.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadUrlResponse.java @@ -3,9 +3,9 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; -public record TempAlbumImageUploadResponse( +public record TempAlbumImageUploadUrlResponse( @Schema(description = "생성된 presigned url 리스트", example = "[1,2,3,4]") List urls) { - public static TempAlbumImageUploadResponse of(List urls) { - return new TempAlbumImageUploadResponse(urls); + public static TempAlbumImageUploadUrlResponse of(List urls) { + return new TempAlbumImageUploadUrlResponse(urls); } } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesConfirmResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesUploadCompleteResponse.java similarity index 53% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesConfirmResponse.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesUploadCompleteResponse.java index fc96aa87..eda6c3e5 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesConfirmResponse.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesUploadCompleteResponse.java @@ -3,9 +3,9 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; -public record TempAlbumImagesConfirmResponse( +public record TempAlbumImagesUploadCompleteResponse( @Schema(description = "생성된 임시 앨범 이미지들의 ID 리스트") List tempAlbumImageIds) { - public static TempAlbumImagesConfirmResponse of(List tempAlbumImageIds) { - return new TempAlbumImagesConfirmResponse(tempAlbumImageIds); + public static TempAlbumImagesUploadCompleteResponse of(List tempAlbumImageIds) { + return new TempAlbumImagesUploadCompleteResponse(tempAlbumImageIds); } } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java index 72d172a2..4271a995 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java @@ -7,14 +7,14 @@ import org.cherrypic.global.pagination.SortParameter; public interface ImageService { - PresignedUrlResponse createMemberProfileImageUploadUrl(ImageUploadRequest request); + ImageUploadUrlResponse createMemberProfileImageUploadUrl(ImageUploadUrlRequest request); - PresignedUrlResponse createAlbumCoverImageUploadUrl(ImageUploadRequest request); + ImageUploadUrlResponse createAlbumCoverImageUploadUrl(ImageUploadUrlRequest request); - PresignedUrlResponse createEventCoverImageUploadUrl(ImageUploadRequest request); + ImageUploadUrlResponse createEventCoverImageUploadUrl(ImageUploadUrlRequest request); - AlbumImageUploadResponse createAlbumImageUploadUrls( - Long albumId, AlbumImageUploadRequest request); + AlbumImageUploadUrlResponse createAlbumImageUploadUrls( + Long albumId, AlbumImageUploadUrlRequest request); SliceResponse getAlbumImages( Long albumId, @@ -32,16 +32,16 @@ SliceResponse getEventImages( void deleteAlbumImage(Long albumId, AlbumImageDeleteRequest request); - TempAlbumImageUploadResponse createTempAlbumImageUploadUrls( - Long tempAlbumId, TempAlbumImageUploadRequest request); + TempAlbumImageUploadUrlResponse createTempAlbumImageUploadUrls( + Long tempAlbumId, TempAlbumImageUploadUrlRequest request); void deleteTempAlbumImage(Long tempAlbumId, TempAlbumImageDeleteRequest request); - void confirmNonAlbumImageUpload(ImageConfirmRequest request); + void completeNonAlbumImageUpload(ImageUploadCompleteRequest request); - AlbumImagesConfirmResponse confirmAlbumImagesUpload( - Long albumId, AlbumImagesConfirmRequest request); + AlbumImagesUploadCompleteResponse completeAlbumImagesUpload( + Long albumId, AlbumImagesUploadCompleteRequest request); - TempAlbumImagesConfirmResponse confirmTempAlbumImagesUpload( - Long tempAlbumId, TempAlbumImagesConfirmRequest request); + TempAlbumImagesUploadCompleteResponse completeTempAlbumImagesUpload( + Long tempAlbumId, TempAlbumImagesUploadCompleteRequest request); } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java index 50b58b62..e7928f07 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java @@ -66,7 +66,7 @@ public class ImageServiceImpl implements ImageService { private final ApplicationEventPublisher eventPublisher; @Override - public PresignedUrlResponse createMemberProfileImageUploadUrl(ImageUploadRequest request) { + public ImageUploadUrlResponse createMemberProfileImageUploadUrl(ImageUploadUrlRequest request) { final Member currentMember = memberUtil.getCurrentMember(); validateImageExtension(request.fileExtension()); @@ -78,11 +78,11 @@ public PresignedUrlResponse createMemberProfileImageUploadUrl(ImageUploadRequest request.fileExtension(), request.md5Hash()); - return PresignedUrlResponse.of(presignedUrl); + return ImageUploadUrlResponse.of(presignedUrl); } @Override - public PresignedUrlResponse createAlbumCoverImageUploadUrl(ImageUploadRequest request) { + public ImageUploadUrlResponse createAlbumCoverImageUploadUrl(ImageUploadUrlRequest request) { final Member currentMember = memberUtil.getCurrentMember(); validateImageExtension(request.fileExtension()); @@ -94,11 +94,11 @@ public PresignedUrlResponse createAlbumCoverImageUploadUrl(ImageUploadRequest re request.fileExtension(), request.md5Hash()); - return PresignedUrlResponse.of(presignedUrl); + return ImageUploadUrlResponse.of(presignedUrl); } @Override - public PresignedUrlResponse createEventCoverImageUploadUrl(ImageUploadRequest request) { + public ImageUploadUrlResponse createEventCoverImageUploadUrl(ImageUploadUrlRequest request) { final Member currentMember = memberUtil.getCurrentMember(); validateImageExtension(request.fileExtension()); @@ -110,12 +110,12 @@ public PresignedUrlResponse createEventCoverImageUploadUrl(ImageUploadRequest re request.fileExtension(), request.md5Hash()); - return PresignedUrlResponse.of(presignedUrl); + return ImageUploadUrlResponse.of(presignedUrl); } @Override - public AlbumImageUploadResponse createAlbumImageUploadUrls( - Long albumId, AlbumImageUploadRequest request) { + public AlbumImageUploadUrlResponse createAlbumImageUploadUrls( + Long albumId, AlbumImageUploadUrlRequest request) { final Member currentMember = memberUtil.getCurrentMember(); final Album album = getAlbumByIdWithLock(albumId); @@ -124,7 +124,7 @@ public AlbumImageUploadResponse createAlbumImageUploadUrls( BigDecimal uploadCapacityMb = request.payloads().stream() - .map(AlbumImageUploadRequest.Payload::capacityMb) + .map(AlbumImageUploadUrlRequest.Payload::capacityMb) .reduce(BigDecimal.ZERO, BigDecimal::add); validateAlbumCapacity(album, uploadCapacityMb); @@ -141,7 +141,7 @@ public AlbumImageUploadResponse createAlbumImageUploadUrls( req.md5Hashes())) .toList(); - return AlbumImageUploadResponse.of(presignedUrls); + return AlbumImageUploadUrlResponse.of(presignedUrls); } @Override @@ -207,8 +207,8 @@ public void deleteAlbumImage(Long albumId, AlbumImageDeleteRequest request) { @Override @Transactional - public TempAlbumImageUploadResponse createTempAlbumImageUploadUrls( - Long tempAlbumId, TempAlbumImageUploadRequest request) { + public TempAlbumImageUploadUrlResponse createTempAlbumImageUploadUrls( + Long tempAlbumId, TempAlbumImageUploadUrlRequest request) { final Member currentMember = memberUtil.getCurrentMember(); final TempAlbum tempAlbum = getTempAlbumById(tempAlbumId); @@ -216,7 +216,7 @@ public TempAlbumImageUploadResponse createTempAlbumImageUploadUrls( BigDecimal uploadCapacityMb = request.payloads().stream() - .map(TempAlbumImageUploadRequest.Payload::capacityMb) + .map(TempAlbumImageUploadUrlRequest.Payload::capacityMb) .reduce(BigDecimal.ZERO, BigDecimal::add); validateTempAlbumCapacity(tempAlbum, uploadCapacityMb); @@ -233,7 +233,7 @@ public TempAlbumImageUploadResponse createTempAlbumImageUploadUrls( req.md5Hashes())) .toList(); - return TempAlbumImageUploadResponse.of(presignedUrls); + return TempAlbumImageUploadUrlResponse.of(presignedUrls); } @Override @@ -265,21 +265,21 @@ public void deleteTempAlbumImage(Long tempAlbumId, TempAlbumImageDeleteRequest r } @Override - public void confirmNonAlbumImageUpload(ImageConfirmRequest request) { + public void completeNonAlbumImageUpload(ImageUploadCompleteRequest request) { validateImageUpload(request.imageUrl()); s3Util.updateTagToCompleteByUrl(request.imageUrl()); } @Override - public AlbumImagesConfirmResponse confirmAlbumImagesUpload( - Long albumId, AlbumImagesConfirmRequest request) { + public AlbumImagesUploadCompleteResponse completeAlbumImagesUpload( + Long albumId, AlbumImagesUploadCompleteRequest request) { final Member currentMember = memberUtil.getCurrentMember(); final Album album = getAlbumById(albumId); List imageUrls = request.payloads().stream() - .map(AlbumImagesConfirmRequest.Payload::imageUrl) + .map(AlbumImagesUploadCompleteRequest.Payload::imageUrl) .toList(); validateImagesUpload(imageUrls); @@ -288,7 +288,7 @@ public AlbumImagesConfirmResponse confirmAlbumImagesUpload( BigDecimal uploadCapacityMb = request.payloads().stream() - .map(AlbumImagesConfirmRequest.Payload::capacityMb) + .map(AlbumImagesUploadCompleteRequest.Payload::capacityMb) .reduce(BigDecimal.ZERO, BigDecimal::add); album.increaseCapacity(uploadCapacityMb); @@ -296,7 +296,7 @@ public AlbumImagesConfirmResponse confirmAlbumImagesUpload( IntStream.range(0, request.payloads().size()) .mapToObj( i -> { - AlbumImagesConfirmRequest.Payload req = + AlbumImagesUploadCompleteRequest.Payload req = request.payloads().get(i); String imageUrl = imageUrls.get(i); @@ -317,17 +317,18 @@ public AlbumImagesConfirmResponse confirmAlbumImagesUpload( imageRepository.findImageIdsByUrlsInOrder( images.stream().map(Image::getUrl).toList()); - return AlbumImagesConfirmResponse.of(imageIds, currentMember.getLocalImageDeletion()); + return AlbumImagesUploadCompleteResponse.of( + imageIds, currentMember.getLocalImageDeletion()); } @Override - public TempAlbumImagesConfirmResponse confirmTempAlbumImagesUpload( - Long tempAlbumId, TempAlbumImagesConfirmRequest request) { + public TempAlbumImagesUploadCompleteResponse completeTempAlbumImagesUpload( + Long tempAlbumId, TempAlbumImagesUploadCompleteRequest request) { final TempAlbum tempAlbum = getTempAlbumById(tempAlbumId); List imageUrls = request.payloads().stream() - .map(TempAlbumImagesConfirmRequest.Payload::tempAlbumImageUrl) + .map(TempAlbumImagesUploadCompleteRequest.Payload::tempAlbumImageUrl) .toList(); validateImagesUpload(imageUrls); @@ -336,7 +337,7 @@ public TempAlbumImagesConfirmResponse confirmTempAlbumImagesUpload( BigDecimal uploadCapacityMb = request.payloads().stream() - .map(TempAlbumImagesConfirmRequest.Payload::capacityMb) + .map(TempAlbumImagesUploadCompleteRequest.Payload::capacityMb) .reduce(BigDecimal.ZERO, BigDecimal::add); tempAlbum.increaseCapacity(uploadCapacityMb); @@ -345,7 +346,7 @@ public TempAlbumImagesConfirmResponse confirmTempAlbumImagesUpload( IntStream.range(0, request.payloads().size()) .mapToObj( i -> { - TempAlbumImagesConfirmRequest.Payload req = + TempAlbumImagesUploadCompleteRequest.Payload req = request.payloads().get(i); String imageUrl = imageUrls.get(i); @@ -360,7 +361,7 @@ public TempAlbumImagesConfirmResponse confirmTempAlbumImagesUpload( imageRepository.findTempImageIdsByUrlsInOrder( tempAlbumImages.stream().map(TempAlbumImage::getUrl).toList()); - return TempAlbumImagesConfirmResponse.of(tempAlbumImageIds); + return TempAlbumImagesUploadCompleteResponse.of(tempAlbumImageIds); } private Album getAlbumById(Long albumId) { @@ -434,10 +435,10 @@ private void validateTempAlbumCapacity(TempAlbum tempAlbum, BigDecimal uploadCap } } - private void validateDistinctHashes(AlbumImageUploadRequest request) { + private void validateDistinctHashes(AlbumImageUploadUrlRequest request) { List hashes = request.payloads().stream() - .map(AlbumImageUploadRequest.Payload::md5Hashes) + .map(AlbumImageUploadUrlRequest.Payload::md5Hashes) .toList(); if (hashes.stream().distinct().count() != hashes.size()) { @@ -445,10 +446,10 @@ private void validateDistinctHashes(AlbumImageUploadRequest request) { } } - private void validateDistinctHashes(TempAlbumImageUploadRequest request) { + private void validateDistinctHashes(TempAlbumImageUploadUrlRequest request) { List hashes = request.payloads().stream() - .map(TempAlbumImageUploadRequest.Payload::md5Hashes) + .map(TempAlbumImageUploadUrlRequest.Payload::md5Hashes) .toList(); if (hashes.stream().distinct().count() != hashes.size()) { diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index 45cad173..62b5318b 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -54,9 +54,10 @@ class 프로필용_Presigned_URL_생성_요청_시 { @Test void 유효한_요청이면_회원_프로필_이미지용_Presigned_URL을_반환한다() throws Exception { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.JPEG, "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.JPEG, "testMd5Hash"); - PresignedUrlResponse response = new PresignedUrlResponse("testPresignedUrl"); + ImageUploadUrlResponse response = new ImageUploadUrlResponse("testPresignedUrl"); given(imageService.createMemberProfileImageUploadUrl(request)).willReturn(response); @@ -76,7 +77,8 @@ class 프로필용_Presigned_URL_생성_요청_시 { @Test void 동영상_확장자를_입력할_경우_예외가_발생한다() throws Exception { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.MKV, "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.MKV, "testMd5Hash"); given(imageService.createMemberProfileImageUploadUrl(request)) .willThrow(new CustomException(ImageErrorCode.NOT_IMAGE_EXTENSION)); @@ -101,8 +103,8 @@ class 프로필용_Presigned_URL_생성_요청_시 { @ValueSource(strings = {"JPEG1", "PDF", "TXT"}) void 이미지_파일_확장자가_null_또는_지원하지_않는_형식이면_예외가_발생한다(String extension) throws Exception { // given - ImageUploadRequest request = - new ImageUploadRequest(FileExtension.from(extension), "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.from(extension), "testMd5Hash"); // when & then ResultActions perform = @@ -127,7 +129,7 @@ class 프로필용_Presigned_URL_생성_요청_시 { @ValueSource(strings = {" "}) void MD5_해시를_비워두면_예외가_발생한다(String md5Hash) throws Exception { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.JPG, md5Hash); + ImageUploadUrlRequest request = new ImageUploadUrlRequest(FileExtension.JPG, md5Hash); // when & then ResultActions perform = @@ -150,9 +152,10 @@ class 앨범_커버용_Presigned_URL_생성_요청_시 { @Test void 유효한_요청이면_앨범_커버_이미지용_Presigned_URL을_반환한다() throws Exception { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.JPEG, "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.JPEG, "testMd5Hash"); - PresignedUrlResponse response = new PresignedUrlResponse("testPresignedUrl"); + ImageUploadUrlResponse response = new ImageUploadUrlResponse("testPresignedUrl"); given(imageService.createAlbumCoverImageUploadUrl(request)).willReturn(response); @@ -172,7 +175,8 @@ class 앨범_커버용_Presigned_URL_생성_요청_시 { @Test void 동영상_확장자를_입력할_경우_예외가_발생한다() throws Exception { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.MKV, "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.MKV, "testMd5Hash"); given(imageService.createAlbumCoverImageUploadUrl(request)) .willThrow(new CustomException(ImageErrorCode.NOT_IMAGE_EXTENSION)); @@ -197,8 +201,8 @@ class 앨범_커버용_Presigned_URL_생성_요청_시 { @ValueSource(strings = {"JPEG1", "PDF", "TXT"}) void 이미지_파일_확장자가_null_또는_지원하지_않는_형식이면_예외가_발생한다(String extension) throws Exception { // given - ImageUploadRequest request = - new ImageUploadRequest(FileExtension.from(extension), "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.from(extension), "testMd5Hash"); // when & then ResultActions perform = @@ -223,7 +227,7 @@ class 앨범_커버용_Presigned_URL_생성_요청_시 { @ValueSource(strings = {" "}) void MD5_해시를_비워두면_예외가_발생한다(String md5Hash) throws Exception { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.JPG, md5Hash); + ImageUploadUrlRequest request = new ImageUploadUrlRequest(FileExtension.JPG, md5Hash); // when & then ResultActions perform = @@ -246,9 +250,10 @@ class 이벤트_커버용_Presigned_URL_생성_요청_시 { @Test void 유효한_요청이면_이벤트_커버_이미지용_Presigned_URL을_반환한다() throws Exception { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.JPEG, "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.JPEG, "testMd5Hash"); - PresignedUrlResponse response = new PresignedUrlResponse("testPresignedUrl"); + ImageUploadUrlResponse response = new ImageUploadUrlResponse("testPresignedUrl"); given(imageService.createEventCoverImageUploadUrl(request)).willReturn(response); @@ -268,7 +273,8 @@ class 이벤트_커버용_Presigned_URL_생성_요청_시 { @Test void 동영상_확장자를_입력할_경우_예외가_발생한다() throws Exception { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.MKV, "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.MKV, "testMd5Hash"); given(imageService.createEventCoverImageUploadUrl(request)) .willThrow(new CustomException(ImageErrorCode.NOT_IMAGE_EXTENSION)); @@ -293,8 +299,8 @@ class 이벤트_커버용_Presigned_URL_생성_요청_시 { @ValueSource(strings = {"JPEG1", "PDF", "TXT"}) void 이미지_파일_확장자가_null_또는_지원하지_않는_형식이면_예외가_발생한다(String extension) throws Exception { // given - ImageUploadRequest request = - new ImageUploadRequest(FileExtension.from(extension), "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.from(extension), "testMd5Hash"); // when & then ResultActions perform = @@ -319,7 +325,7 @@ class 이벤트_커버용_Presigned_URL_생성_요청_시 { @ValueSource(strings = {" "}) void MD5_해시를_비워두면_예외가_발생한다(String md5Hash) throws Exception { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.JPG, md5Hash); + ImageUploadUrlRequest request = new ImageUploadUrlRequest(FileExtension.JPG, md5Hash); // when & then ResultActions perform = @@ -342,23 +348,24 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 유효한_요청이면_이미지_업로드_Presigned_URL들을_반환한다() throws Exception { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); - AlbumImageUploadResponse response = - new AlbumImageUploadResponse(List.of("testPresignedUrl1", "testPresignedUrl2")); + AlbumImageUploadUrlResponse response = + new AlbumImageUploadUrlResponse( + List.of("testPresignedUrl1", "testPresignedUrl2")); given(imageService.createAlbumImageUploadUrls(1L, request)).willReturn(response); // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/images") + post("/albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -371,12 +378,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 앨범이_존재하지_않는_경우_예외가_발생한다() throws Exception { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) @@ -385,7 +392,7 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/images") + post("/albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -399,12 +406,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 앨범에_속하지_않은_사용자가_앨범_이미지_업로드_URL을_요청하면_예외가_발생한다() throws Exception { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) @@ -413,7 +420,7 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/images") + post("/albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -427,12 +434,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void LIMITED_권한의_사용자가_앨범_이미지_업로드_URL을_요청하면_예외가_발생한다() throws Exception { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) @@ -441,7 +448,7 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/images") + post("/albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -455,12 +462,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 구독이_만료된_앨범인_경우_예외가_발생한다() throws Exception { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) @@ -470,7 +477,7 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/images") + post("/albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -484,12 +491,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 앨범의_남은_용량을_초과해서_요청하면_예외가_발생한다() throws Exception { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) @@ -498,7 +505,7 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/images") + post("/albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -512,12 +519,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void MD5_해시에_중복된_값이_존재하면_예외가_발생한다() throws Exception { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash", BigDecimal.ONE), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) @@ -526,7 +533,7 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/images") + post("/albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -543,10 +550,10 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @ValueSource(strings = {"JPEG1", "PDF", "TXT"}) void 파일_확장자가_null_또는_지원하지_않는_형식이면_예외가_발생한다(String extension) throws Exception { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.from(extension), "testMd5Hash1", BigDecimal.ONE))); @@ -554,7 +561,7 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/images") + post("/albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -571,16 +578,16 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 이미지_용량을_비워두면_예외가_발생한다() throws Exception { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash", null))); // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/images") + post("/albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -597,16 +604,16 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @ValueSource(strings = {" "}) void MD5_해시가_null_또는_공백이면_예외가_발생한다(String md5Hash) throws Exception { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, md5Hash, BigDecimal.ONE))); // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/images") + post("/albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -620,12 +627,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 업로드_요청_정보를_비워두면_예외가_발생한다() throws Exception { // given - AlbumImageUploadRequest request = new AlbumImageUploadRequest(List.of()); + AlbumImageUploadUrlRequest request = new AlbumImageUploadUrlRequest(List.of()); // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/images") + post("/albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1336,20 +1343,20 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 유효한_요청이면_임시_앨범_이미지_업로드_Presigned_URL들을_반환한다() throws Exception { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", new BigDecimal("0.3")), - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", new BigDecimal("0.3")))); - TempAlbumImageUploadResponse response = - new TempAlbumImageUploadResponse( + TempAlbumImageUploadUrlResponse response = + new TempAlbumImageUploadUrlResponse( List.of("testPresignedUrl1", "testPresignedUrl2")); given(imageService.createTempAlbumImageUploadUrls(1L, request)).willReturn(response); @@ -1357,7 +1364,7 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/images") + post("/temp-albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1370,14 +1377,14 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 임시_앨범이_존재하지_않는_경우_예외가_발생한다() throws Exception { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", new BigDecimal("0.3")), - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", new BigDecimal("0.3")))); @@ -1388,7 +1395,7 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/images") + post("/temp-albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1402,14 +1409,14 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 임시_앨범_소유자가_아닌_사용자가_앨범_이미지_업로드_URL을_요청하면_예외가_발생한다() throws Exception { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", new BigDecimal("0.3")), - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", new BigDecimal("0.3")))); @@ -1420,7 +1427,7 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/images") + post("/temp-albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1434,14 +1441,14 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 임시_앨범의_남은_용량을_초과해서_요청하면_예외가_발생한다() throws Exception { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", TempAlbumType.DEFAULT.getCapacityMb()), - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createTempAlbumImageUploadUrls(1L, request)) @@ -1451,7 +1458,7 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/images") + post("/temp-albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1465,14 +1472,14 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void MD5_해시에_중복된_값이_존재하면_예외가_발생한다() throws Exception { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", new BigDecimal("0.3")), - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", new BigDecimal("0.3")))); @@ -1483,7 +1490,7 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/images") + post("/temp-albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1500,10 +1507,10 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @ValueSource(strings = {"JPEG1", "PDF", "TXT"}) void 파일_확장자가_null_또는_지원하지_않는_형식이면_예외가_발생한다(String extension) throws Exception { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.from(extension), "testMd5Hash1", BigDecimal.ONE))); @@ -1511,7 +1518,7 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/images") + post("/temp-albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1528,16 +1535,16 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 이미지_용량을_비워두면_예외가_발생한다() throws Exception { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash", null))); // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/images") + post("/temp-albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1554,16 +1561,16 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @ValueSource(strings = {" "}) void MD5_해시가_null_또는_공백이면_예외가_발생한다(String md5Hash) throws Exception { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, md5Hash, BigDecimal.ONE))); // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/images") + post("/temp-albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1577,12 +1584,12 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 업로드_요청_정보를_비워두면_예외가_발생한다() throws Exception { // given - TempAlbumImageUploadRequest request = new TempAlbumImageUploadRequest(List.of()); + TempAlbumImageUploadUrlRequest request = new TempAlbumImageUploadUrlRequest(List.of()); // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/images") + post("/temp-albums/1/upload-url") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1713,14 +1720,14 @@ class 앨범_외_이미지_업로드_검증_요청_시 { @Test void 유효한_요청이면_NO_CONTENT를_반환한다() throws Exception { // given - ImageConfirmRequest request = new ImageConfirmRequest("testImageUrl"); + ImageUploadCompleteRequest request = new ImageUploadCompleteRequest("testImageUrl"); - willDoNothing().given(imageService).confirmNonAlbumImageUpload(request); + willDoNothing().given(imageService).completeNonAlbumImageUpload(request); // when & then ResultActions perform = mockMvc.perform( - post("/image/confirm-non-album") + post("/image/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1732,16 +1739,16 @@ class 앨범_외_이미지_업로드_검증_요청_시 { @Test void 이미지_업로드_실패_시_예외가_발생한다() throws Exception { // given - ImageConfirmRequest request = new ImageConfirmRequest("testImageUrl"); + ImageUploadCompleteRequest request = new ImageUploadCompleteRequest("testImageUrl"); willThrow(new CustomException(ImageErrorCode.IMAGE_UPLOAD_FAIL)) .given(imageService) - .confirmNonAlbumImageUpload(request); + .completeNonAlbumImageUpload(request); // when & then ResultActions perform = mockMvc.perform( - post("/image/confirm-non-album") + post("/image/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1758,12 +1765,12 @@ class 앨범_외_이미지_업로드_검증_요청_시 { @ValueSource(strings = {" "}) void 이미지_url을_비워두면_예외가_발생한다(String imageUrl) throws Exception { // given - ImageConfirmRequest request = new ImageConfirmRequest(imageUrl); + ImageUploadCompleteRequest request = new ImageUploadCompleteRequest(imageUrl); // when & then ResultActions perform = mockMvc.perform( - post("/image/confirm-non-album") + post("/image/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1781,23 +1788,23 @@ class 앨범_이미지_업로드_요청_시 { @Test void 유효한_요청이면_생성된_이미지_ID와_로컬_이미지_삭제_여부를_반환한다() throws Exception { // given - AlbumImagesConfirmRequest request = - new AlbumImagesConfirmRequest( + AlbumImagesUploadCompleteRequest request = + new AlbumImagesUploadCompleteRequest( List.of( - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, "testImageUrl1"), - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); - AlbumImagesConfirmResponse response = - new AlbumImagesConfirmResponse(false, List.of(1L, 2L)); + AlbumImagesUploadCompleteResponse response = + new AlbumImagesUploadCompleteResponse(false, List.of(1L, 2L)); - given(imageService.confirmAlbumImagesUpload(1L, request)).willReturn(response); + given(imageService.completeAlbumImagesUpload(1L, request)).willReturn(response); // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/confirm-images-upload") + post("/albums/1/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1811,21 +1818,21 @@ class 앨범_이미지_업로드_요청_시 { @Test void 앨범이_존재하지_않는_경우_예외가_발생한다() throws Exception { // given - AlbumImagesConfirmRequest request = - new AlbumImagesConfirmRequest( + AlbumImagesUploadCompleteRequest request = + new AlbumImagesUploadCompleteRequest( List.of( - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, "testImageUrl1"), - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); - given(imageService.confirmAlbumImagesUpload(1L, request)) + given(imageService.completeAlbumImagesUpload(1L, request)) .willThrow(new CustomException(AlbumErrorCode.ALBUM_NOT_FOUND)); // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/confirm-images-upload") + post("/albums/1/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1839,21 +1846,21 @@ class 앨범_이미지_업로드_요청_시 { @Test void 모든_이미지를_업로드_성공하지_않았을_경우_예외가_발생한다() throws Exception { // given - AlbumImagesConfirmRequest request = - new AlbumImagesConfirmRequest( + AlbumImagesUploadCompleteRequest request = + new AlbumImagesUploadCompleteRequest( List.of( - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, "testImageUrl1"), - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); - given(imageService.confirmAlbumImagesUpload(1L, request)) + given(imageService.completeAlbumImagesUpload(1L, request)) .willThrow(new CustomException(ImageErrorCode.IMAGE_UPLOAD_FAIL)); // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/confirm-images-upload") + post("/albums/1/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1867,12 +1874,13 @@ class 앨범_이미지_업로드_요청_시 { @Test void 검증하고자_하는_이미지들의_정보를_비워두면_예외가_발생한다() throws Exception { // given - AlbumImagesConfirmRequest request = new AlbumImagesConfirmRequest(List.of()); + AlbumImagesUploadCompleteRequest request = + new AlbumImagesUploadCompleteRequest(List.of()); // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/confirm-images-upload") + post("/albums/1/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1886,16 +1894,16 @@ class 앨범_이미지_업로드_요청_시 { @Test void 업로드_하는_파일의_용량을_비워두면_예외가_발생한다() throws Exception { // given - AlbumImagesConfirmRequest request = - new AlbumImagesConfirmRequest( + AlbumImagesUploadCompleteRequest request = + new AlbumImagesUploadCompleteRequest( List.of( - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), null, "testImageUrl1"))); // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/confirm-images-upload") + post("/albums/1/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1912,16 +1920,16 @@ class 앨범_이미지_업로드_요청_시 { @ValueSource(strings = {" "}) void 검증_요청_이미지_url을_비워두면_예외가_발생한다(String imageUrl) throws Exception { // given - AlbumImagesConfirmRequest request = - new AlbumImagesConfirmRequest( + AlbumImagesUploadCompleteRequest request = + new AlbumImagesUploadCompleteRequest( List.of( - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, imageUrl))); // when & then ResultActions perform = mockMvc.perform( - post("/albums/1/confirm-images-upload") + post("/albums/1/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1939,23 +1947,23 @@ class 임시_앨범_이미지_업로드_요청_시 { @Test void 유효한_요청이면_생성된_임시_앨범_이미지_ID들을_반환한다() throws Exception { // given - TempAlbumImagesConfirmRequest request = - new TempAlbumImagesConfirmRequest( + TempAlbumImagesUploadCompleteRequest request = + new TempAlbumImagesUploadCompleteRequest( List.of( - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, "testImageUrl1"), - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, "testImageUrl2"))); - TempAlbumImagesConfirmResponse response = - new TempAlbumImagesConfirmResponse(List.of(1L, 2L)); + TempAlbumImagesUploadCompleteResponse response = + new TempAlbumImagesUploadCompleteResponse(List.of(1L, 2L)); - given(imageService.confirmTempAlbumImagesUpload(1L, request)).willReturn(response); + given(imageService.completeTempAlbumImagesUpload(1L, request)).willReturn(response); // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/confirm-images-upload") + post("/temp-albums/1/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1968,21 +1976,21 @@ class 임시_앨범_이미지_업로드_요청_시 { @Test void 임시_앨범이_존재하지_않는_경우_예외가_발생한다() throws Exception { // given - TempAlbumImagesConfirmRequest request = - new TempAlbumImagesConfirmRequest( + TempAlbumImagesUploadCompleteRequest request = + new TempAlbumImagesUploadCompleteRequest( List.of( - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, "testImageUrl1"), - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, "testImageUrl2"))); - given(imageService.confirmTempAlbumImagesUpload(1L, request)) + given(imageService.completeTempAlbumImagesUpload(1L, request)) .willThrow(new CustomException(TempAlbumErrorCode.TEMP_ALBUM_NOT_FOUND)); // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/confirm-images-upload") + post("/temp-albums/1/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1996,21 +2004,21 @@ class 임시_앨범_이미지_업로드_요청_시 { @Test void 모든_이미지를_업로드_성공하지_않았을_경우_예외가_발생한다() throws Exception { // given - TempAlbumImagesConfirmRequest request = - new TempAlbumImagesConfirmRequest( + TempAlbumImagesUploadCompleteRequest request = + new TempAlbumImagesUploadCompleteRequest( List.of( - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, "testImageUrl1"), - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, "testImageUrl2"))); - given(imageService.confirmTempAlbumImagesUpload(1L, request)) + given(imageService.completeTempAlbumImagesUpload(1L, request)) .willThrow(new CustomException(ImageErrorCode.IMAGE_UPLOAD_FAIL)); // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/confirm-images-upload") + post("/temp-albums/1/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -2024,12 +2032,13 @@ class 임시_앨범_이미지_업로드_요청_시 { @Test void 검증하고자_하는_이미지들의_정보를_비워두면_예외가_발생한다() throws Exception { // given - TempAlbumImagesConfirmRequest request = new TempAlbumImagesConfirmRequest(List.of()); + TempAlbumImagesUploadCompleteRequest request = + new TempAlbumImagesUploadCompleteRequest(List.of()); // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/confirm-images-upload") + post("/temp-albums/1/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -2045,16 +2054,16 @@ class 임시_앨범_이미지_업로드_요청_시 { @Test void 업로드_하는_파일의_용량을_비워두면_예외가_발생한다() throws Exception { // given - TempAlbumImagesConfirmRequest request = - new TempAlbumImagesConfirmRequest( + TempAlbumImagesUploadCompleteRequest request = + new TempAlbumImagesUploadCompleteRequest( List.of( - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( null, "testImageUrl1"))); // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/confirm-images-upload") + post("/temp-albums/1/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -2071,16 +2080,16 @@ class 임시_앨범_이미지_업로드_요청_시 { @ValueSource(strings = {" "}) void 검증_요청_이미지_url을_비워두면_예외가_발생한다(String imageUrl) throws Exception { // given - TempAlbumImagesConfirmRequest request = - new TempAlbumImagesConfirmRequest( + TempAlbumImagesUploadCompleteRequest request = + new TempAlbumImagesUploadCompleteRequest( List.of( - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, imageUrl))); // when & then ResultActions perform = mockMvc.perform( - post("/temp-albums/1/confirm-images-upload") + post("/temp-albums/1/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java index 2526c471..47fc5d15 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java @@ -95,7 +95,8 @@ void setUp() { @Test void 유효한_요청이면_회원_프로필_이미지용_Presigned_URL을_생성한다() { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.JPEG, "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.JPEG, "testMd5Hash"); given( s3Util.createPresignedUrl( ImageType.MEMBER_PROFILE, @@ -114,7 +115,8 @@ void setUp() { + " + \"&Content-MD5=testMd5Hash\""); // when - PresignedUrlResponse response = imageService.createMemberProfileImageUploadUrl(request); + ImageUploadUrlResponse response = + imageService.createMemberProfileImageUploadUrl(request); // then assertThat(response.presignedUrl()) @@ -126,7 +128,8 @@ void setUp() { @Test void 동영상_확장자를_입력할_경우_예외가_발생한다() { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.MKV, "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.MKV, "testMd5Hash"); // when & then assertThatThrownBy(() -> imageService.createMemberProfileImageUploadUrl(request)) @@ -163,7 +166,8 @@ void setUp() { @Test void 유효한_요청이면_앨범_커버_이미지용_Presigned_URL을_생성한다() { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.JPEG, "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.JPEG, "testMd5Hash"); given( s3Util.createPresignedUrl( ImageType.ALBUM_COVER, 1L, FileExtension.JPEG, "testMd5Hash")) @@ -179,7 +183,7 @@ void setUp() { + "&Content-MD5=testMd5Hash"); // when - PresignedUrlResponse response = imageService.createAlbumCoverImageUploadUrl(request); + ImageUploadUrlResponse response = imageService.createAlbumCoverImageUploadUrl(request); // then assertThat(response.presignedUrl()) @@ -190,7 +194,8 @@ void setUp() { @Test void 동영상_확장자를_입력할_경우_예외가_발생한다() { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.MKV, "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.MKV, "testMd5Hash"); // when & then assertThatThrownBy(() -> imageService.createAlbumCoverImageUploadUrl(request)) @@ -232,7 +237,8 @@ void setUp() { @Test void 유효한_요청이면_이벤트_커버_이미지용_Presigned_URL을_생성한다() { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.JPEG, "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.JPEG, "testMd5Hash"); given( s3Util.createPresignedUrl( ImageType.EVENT_COVER, 1L, FileExtension.JPEG, "testMd5Hash")) @@ -248,7 +254,7 @@ void setUp() { + "&Content-MD5=testMd5Hash"); // when - PresignedUrlResponse response = imageService.createEventCoverImageUploadUrl(request); + ImageUploadUrlResponse response = imageService.createEventCoverImageUploadUrl(request); // then assertThat(response.presignedUrl()) @@ -259,7 +265,8 @@ void setUp() { @Test void 동영상_확장자를_입력할_경우_예외가_발생한다() { // given - ImageUploadRequest request = new ImageUploadRequest(FileExtension.MKV, "testMd5Hash"); + ImageUploadUrlRequest request = + new ImageUploadUrlRequest(FileExtension.MKV, "testMd5Hash"); // when & then assertThatThrownBy(() -> imageService.createEventCoverImageUploadUrl(request)) @@ -305,12 +312,12 @@ void setUp() { @Test void 유효한_요청이면_Presigned_URL들을_반환한다() { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given( s3Util.createPresignedUrl( @@ -339,7 +346,7 @@ void setUp() { + "&Content-MD5=testMd5Hash2"); // when - AlbumImageUploadResponse response = + AlbumImageUploadUrlResponse response = imageService.createAlbumImageUploadUrls(1L, request); // then @@ -361,12 +368,12 @@ void setUp() { @Test void 앨범이_존재하지_않는_경우_예외가_발생한다() { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then @@ -378,12 +385,12 @@ void setUp() { @Test void 앨범에_속하지_않은_사용자가_앨범_이미지_업로드_URL을_요청하면_예외가_발생한다() { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then @@ -395,12 +402,12 @@ void setUp() { @Test void LIMITED_권한의_사용자가_앨범_이미지_업로드_URL을_요청하면_예외가_발생한다() { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then @@ -412,12 +419,12 @@ void setUp() { @Test void 구독이_만료된_앨범인_경우_예외가_발생한다() { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then @@ -429,14 +436,14 @@ void setUp() { @Test void 앨범의_남은_용량을_초과해서_요청하면_예외가_발생한다() { /// given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", AlbumType.BASIC.getCapacityMb()), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then @@ -448,12 +455,12 @@ void setUp() { @Test void 해시값에_중복이_존재하면_예외가_발생한다() { // given - AlbumImageUploadRequest request = - new AlbumImageUploadRequest( + AlbumImageUploadUrlRequest request = + new AlbumImageUploadUrlRequest( List.of( - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO), - new AlbumImageUploadRequest.Payload( + new AlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO))); // when & then assertThatThrownBy(() -> imageService.createAlbumImageUploadUrls(1L, request)) @@ -957,14 +964,14 @@ void setUp() { @Test void 유효한_요청이면_Presigned_URL들을_반환한다() { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", new BigDecimal("0.3")), - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", new BigDecimal("0.3")))); @@ -995,7 +1002,7 @@ void setUp() { + "&Content-MD5=testMd5Hash2"); // when - TempAlbumImageUploadResponse response = + TempAlbumImageUploadUrlResponse response = imageService.createTempAlbumImageUploadUrls(1L, request); // then @@ -1017,12 +1024,12 @@ void setUp() { @Test void 임시_앨범이_존재하지_않는_경우_예외가_발생한다() { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO), - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ZERO))); // when & then @@ -1034,12 +1041,12 @@ void setUp() { @Test void 임시_앨범의_소유자가_아닌_사람이_이미지_업로드를_시도하면_예외가_발생한다() { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO), - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ZERO))); // when & then @@ -1051,14 +1058,14 @@ void setUp() { @Test void 임시_앨범의_남은_용량을_초과해서_요청하면_예외가_발생한다() { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", TempAlbumType.DEFAULT.getCapacityMb()), - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then @@ -1070,12 +1077,12 @@ void setUp() { @Test void 해시값에_중복이_존재하면_예외가_발생한다() { // given - TempAlbumImageUploadRequest request = - new TempAlbumImageUploadRequest( + TempAlbumImageUploadUrlRequest request = + new TempAlbumImageUploadUrlRequest( List.of( - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO), - new TempAlbumImageUploadRequest.Payload( + new TempAlbumImageUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO))); // when & then assertThatThrownBy(() -> imageService.createTempAlbumImageUploadUrls(1L, request)) @@ -1189,21 +1196,21 @@ class 앨범_외_이미지_업로드를_검증할_때 { @Test void 업로드_성공_시_예외가_발생하지_않는다() { // given - ImageConfirmRequest request = new ImageConfirmRequest("testImageUrl"); + ImageUploadCompleteRequest request = new ImageUploadCompleteRequest("testImageUrl"); given(s3Util.doesFileExistByUrl("testImageUrl")).willReturn(true); // when & then - assertDoesNotThrow(() -> imageService.confirmNonAlbumImageUpload(request)); + assertDoesNotThrow(() -> imageService.completeNonAlbumImageUpload(request)); } @Test void 업로드_실패_시_예외가_발생한다() { // given - ImageConfirmRequest request = new ImageConfirmRequest("testImageUrl"); + ImageUploadCompleteRequest request = new ImageUploadCompleteRequest("testImageUrl"); given(s3Util.doesFileExistByUrl("testImageUrl")).willReturn(false); // when & then - assertThatThrownBy(() -> imageService.confirmNonAlbumImageUpload(request)) + assertThatThrownBy(() -> imageService.completeNonAlbumImageUpload(request)) .isInstanceOf(CustomException.class) .hasMessage(ImageErrorCode.IMAGE_UPLOAD_FAIL.getMessage()); } @@ -1230,12 +1237,12 @@ void setUp() { @Test void 유효한_요청이면_이미지를_생성한다() { // given - AlbumImagesConfirmRequest request = - new AlbumImagesConfirmRequest( + AlbumImagesUploadCompleteRequest request = + new AlbumImagesUploadCompleteRequest( List.of( - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, "testImageUrl1"), - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); given(s3Util.doAllFilesExistByUrls(List.of("testImageUrl1", "testImageUrl2"))) @@ -1245,8 +1252,8 @@ void setUp() { .updateTagsToCompleteByUrls(List.of("testImageUrl1", "testImageUrl2")); // when - AlbumImagesConfirmResponse response = - imageService.confirmAlbumImagesUpload(1L, request); + AlbumImagesUploadCompleteResponse response = + imageService.completeAlbumImagesUpload(1L, request); // then Assertions.assertAll( @@ -1260,16 +1267,16 @@ void setUp() { @Test void 앨범이_존재하지_않는_경우_예외가_발생한다() { // given - AlbumImagesConfirmRequest request = - new AlbumImagesConfirmRequest( + AlbumImagesUploadCompleteRequest request = + new AlbumImagesUploadCompleteRequest( List.of( - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, "testImageUrl1"), - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); // when & then - assertThatThrownBy(() -> imageService.confirmAlbumImagesUpload(999L, request)) + assertThatThrownBy(() -> imageService.completeAlbumImagesUpload(999L, request)) .isInstanceOf(CustomException.class) .hasMessage(AlbumErrorCode.ALBUM_NOT_FOUND.getMessage()); } @@ -1277,18 +1284,18 @@ void setUp() { @Test void 모든_이미지를_업로드_성공하지_않았을_경우_예외가_발생한다() { // given - AlbumImagesConfirmRequest request = - new AlbumImagesConfirmRequest( + AlbumImagesUploadCompleteRequest request = + new AlbumImagesUploadCompleteRequest( List.of( - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, "testImageUrl1"), - new AlbumImagesConfirmRequest.Payload( + new AlbumImagesUploadCompleteRequest.Payload( LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); given(s3Util.doAllFilesExistByUrls(List.of("testImageUrl1", "testImageUrl2"))) .willReturn(false); // when & then - assertThatThrownBy(() -> imageService.confirmAlbumImagesUpload(1L, request)) + assertThatThrownBy(() -> imageService.completeAlbumImagesUpload(1L, request)) .isInstanceOf(CustomException.class) .hasMessage(ImageErrorCode.IMAGE_UPLOAD_FAIL.getMessage()); } @@ -1314,12 +1321,12 @@ void setUp() { @Test void 유효한_요청이면_임시_앨범_이미지를_생성한다() { // given - TempAlbumImagesConfirmRequest request = - new TempAlbumImagesConfirmRequest( + TempAlbumImagesUploadCompleteRequest request = + new TempAlbumImagesUploadCompleteRequest( List.of( - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, "testImageUrl1"), - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, "testImageUrl2"))); given(s3Util.doAllFilesExistByUrls(List.of("testImageUrl1", "testImageUrl2"))) @@ -1329,8 +1336,8 @@ void setUp() { .updateTagsToCompleteByUrls(List.of("testImageUrl1", "testImageUrl2")); // when - TempAlbumImagesConfirmResponse response = - imageService.confirmTempAlbumImagesUpload(1L, request); + TempAlbumImagesUploadCompleteResponse response = + imageService.completeTempAlbumImagesUpload(1L, request); // then Assertions.assertAll( @@ -1343,16 +1350,16 @@ void setUp() { @Test void 임시_앨범이_존재하지_않는_경우_예외가_발생한다() { // given - TempAlbumImagesConfirmRequest request = - new TempAlbumImagesConfirmRequest( + TempAlbumImagesUploadCompleteRequest request = + new TempAlbumImagesUploadCompleteRequest( List.of( - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, "testImageUrl1"), - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, "testImageUrl2"))); // when & then - assertThatThrownBy(() -> imageService.confirmTempAlbumImagesUpload(999L, request)) + assertThatThrownBy(() -> imageService.completeTempAlbumImagesUpload(999L, request)) .isInstanceOf(CustomException.class) .hasMessage(TempAlbumErrorCode.TEMP_ALBUM_NOT_FOUND.getMessage()); } @@ -1360,19 +1367,19 @@ void setUp() { @Test void 모든_이미지를_업로드_성공하지_않았을_경우_예외가_발생한다() { // given - TempAlbumImagesConfirmRequest request = - new TempAlbumImagesConfirmRequest( + TempAlbumImagesUploadCompleteRequest request = + new TempAlbumImagesUploadCompleteRequest( List.of( - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, "testImageUrl1"), - new TempAlbumImagesConfirmRequest.Payload( + new TempAlbumImagesUploadCompleteRequest.Payload( BigDecimal.ONE, "testImageUrl2"))); given(s3Util.doAllFilesExistByUrls(List.of("testImageUrl1", "testImageUrl2"))) .willReturn(false); // when & then - assertThatThrownBy(() -> imageService.confirmTempAlbumImagesUpload(1L, request)) + assertThatThrownBy(() -> imageService.completeTempAlbumImagesUpload(1L, request)) .isInstanceOf(CustomException.class) .hasMessage(ImageErrorCode.IMAGE_UPLOAD_FAIL.getMessage()); } From 32c173ae6246a58376a4c49ea85b344bb08d6860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Sat, 1 Nov 2025 16:08:26 +0900 Subject: [PATCH 12/16] =?UTF-8?q?fix:=20=EA=B8=B0=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/controller/ImageController.java | 2 +- .../AlbumImagesUploadCompleteRequest.java | 8 ++--- .../request/ImageUploadCompleteRequest.java | 2 +- .../TempAlbumImagesUploadCompleteRequest.java | 8 ++--- .../image/controller/ImageControllerTest.java | 35 ++++++++++--------- .../image/service/ImageServiceTest.java | 6 ++-- 6 files changed, 32 insertions(+), 29 deletions(-) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java index af82262f..be52c75f 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java @@ -52,7 +52,7 @@ public ImageUploadUrlResponse eventCoverImageUploadUrlCreate( return imageService.createEventCoverImageUploadUrl(request); } - @PostMapping("/image/upload-complete") + @PostMapping("/images/upload-complete") @Operation(summary = "앨범 사진 외 이미지 업로드 완료", description = "프로필, 커버 사진 등의 이미지 업로드를 완료합니다.") public ResponseEntity nonAlbumImageUploadComplete( @Valid @RequestBody ImageUploadCompleteRequest request) { diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesUploadCompleteRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesUploadCompleteRequest.java index 92b34c99..34ecf19f 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesUploadCompleteRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesUploadCompleteRequest.java @@ -10,9 +10,9 @@ import java.util.List; public record AlbumImagesUploadCompleteRequest( - @NotEmpty(message = "검증하고자 하는 이미지들의 정보들은 비워둘 수 없습니다.") + @NotEmpty(message = "업로드 완료 하는 이미지들의 정보들은 비워둘 수 없습니다.") @Valid - @Schema(description = "검증 요청 리스트") + @Schema(description = "업로드 완료 요청 리스트") List payloads) { @Schema(name = "AlbumImagesUploadCompletePayload") public record Payload( @@ -20,8 +20,8 @@ public record Payload( @NotNull(message = "파일의 용량은 비워둘 수 없습니다.") @Schema(description = "업로드 하는 파일의 용량(MB), 소수점 2자리 까지", example = "0.04") BigDecimal capacityMb, - @NotBlank(message = "검증하고자 하는 imageUrl은 비워둘 수 없습니다.") + @NotBlank(message = "업로드 완료 하고자 하는 imageUrl은 비워둘 수 없습니다.") @Valid - @Schema(description = "검증 요청 이미지 Url") + @Schema(description = "엄로드 완료 요청 이미지 Url") String imageUrl) {} } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadCompleteRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadCompleteRequest.java index 12f1d307..ae47aea1 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadCompleteRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/ImageUploadCompleteRequest.java @@ -5,5 +5,5 @@ public record ImageUploadCompleteRequest( @NotBlank(message = "이미지 url을 비워둘 수 없습니다.") - @Schema(description = "검증하고자 하는 이미지 url", example = "https://example.jpg") + @Schema(description = "업로드 완료 하고자 하는 이미지 url", example = "https://example.jpg") String imageUrl) {} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesUploadCompleteRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesUploadCompleteRequest.java index 4d4999a4..63f3e8b5 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesUploadCompleteRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesUploadCompleteRequest.java @@ -9,17 +9,17 @@ import java.util.List; public record TempAlbumImagesUploadCompleteRequest( - @NotEmpty(message = "검증하고자 하는 임시 앨범 이미지들의 정보들은 비워둘 수 없습니다.") + @NotEmpty(message = "업로드 완료 하고자 하는 임시 앨범 이미지들의 정보들은 비워둘 수 없습니다.") @Valid - @Schema(description = "검증 요청 리스트") + @Schema(description = "업로드 완료 요청 리스트") List payloads) { @Schema(name = "TempAlbumImagesUploadCompletePayload") public record Payload( @NotNull(message = "파일의 용량은 비워둘 수 없습니다.") @Schema(description = "업로드 하는 파일의 용량(MB), 소수점 2자리 까지", example = "0.04") BigDecimal capacityMb, - @NotBlank(message = "검증하고자 하는 tempAlbumImageUrl은 비워둘 수 없습니다.") + @NotBlank(message = "업로드 완료 하고자 하는 tempAlbumImageUrl은 비워둘 수 없습니다.") @Valid - @Schema(description = "검증 요청 임시 앨범 이미지 Url") + @Schema(description = "업로드 완료 요청 임시 앨범 이미지 Url") String tempAlbumImageUrl) {} } diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index 62b5318b..473bcb4c 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -1715,7 +1715,7 @@ class 임시_앨범_이미지_삭제_요청_시 { } @Nested - class 앨범_외_이미지_업로드_검증_요청_시 { + class 앨범_외_이미지_업로드_완료_요청_시 { @Test void 유효한_요청이면_NO_CONTENT를_반환한다() throws Exception { @@ -1727,7 +1727,7 @@ class 앨범_외_이미지_업로드_검증_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/image/upload-complete") + post("/images/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1748,7 +1748,7 @@ class 앨범_외_이미지_업로드_검증_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/image/upload-complete") + post("/images/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1770,7 +1770,7 @@ class 앨범_외_이미지_업로드_검증_요청_시 { // when & then ResultActions perform = mockMvc.perform( - post("/image/upload-complete") + post("/images/upload-complete") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); @@ -1808,9 +1808,9 @@ class 앨범_이미지_업로드_요청_시 { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); - perform.andExpect(status().isOk()) + perform.andExpect(status().isCreated()) .andExpect(jsonPath("$.success").value(true)) - .andExpect(jsonPath("$.status").value(HttpStatus.OK.value())) + .andExpect(jsonPath("$.status").value(HttpStatus.CREATED.value())) .andExpect(jsonPath("$.data.localImageDeletion").value(false)) .andExpect(jsonPath("$.data.imageIds").value(Matchers.contains(1, 2))); } @@ -1872,7 +1872,7 @@ class 앨범_이미지_업로드_요청_시 { } @Test - void 검증하고자_하는_이미지들의_정보를_비워두면_예외가_발생한다() throws Exception { + void 업로드_완료_하고자_하는_이미지들의_정보를_비워두면_예외가_발생한다() throws Exception { // given AlbumImagesUploadCompleteRequest request = new AlbumImagesUploadCompleteRequest(List.of()); @@ -1888,7 +1888,8 @@ class 앨범_이미지_업로드_요청_시 { .andExpect(jsonPath("$.success").value(false)) .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) .andExpect(jsonPath("$.data.code").value("MethodArgumentNotValidException")) - .andExpect(jsonPath("$.data.message").value("검증하고자 하는 이미지들의 정보들은 비워둘 수 없습니다.")); + .andExpect( + jsonPath("$.data.message").value("업로드 완료 하는 이미지들의 정보들은 비워둘 수 없습니다.")); } @Test @@ -1918,7 +1919,7 @@ class 앨범_이미지_업로드_요청_시 { @NullSource @EmptySource @ValueSource(strings = {" "}) - void 검증_요청_이미지_url을_비워두면_예외가_발생한다(String imageUrl) throws Exception { + void 업로드_완료_요청_이미지_url을_비워두면_예외가_발생한다(String imageUrl) throws Exception { // given AlbumImagesUploadCompleteRequest request = new AlbumImagesUploadCompleteRequest( @@ -1937,7 +1938,9 @@ class 앨범_이미지_업로드_요청_시 { .andExpect(jsonPath("$.success").value(false)) .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) .andExpect(jsonPath("$.data.code").value("MethodArgumentNotValidException")) - .andExpect(jsonPath("$.data.message").value("검증하고자 하는 imageUrl은 비워둘 수 없습니다.")); + .andExpect( + jsonPath("$.data.message") + .value("업로드 완료 하고자 하는 imageUrl은 비워둘 수 없습니다.")); } } @@ -1967,9 +1970,9 @@ class 임시_앨범_이미지_업로드_요청_시 { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))); - perform.andExpect(status().isOk()) + perform.andExpect(status().isCreated()) .andExpect(jsonPath("$.success").value(true)) - .andExpect(jsonPath("$.status").value(HttpStatus.OK.value())) + .andExpect(jsonPath("$.status").value(HttpStatus.CREATED.value())) .andExpect(jsonPath("$.data.tempAlbumImageIds").value(Matchers.contains(1, 2))); } @@ -2030,7 +2033,7 @@ class 임시_앨범_이미지_업로드_요청_시 { } @Test - void 검증하고자_하는_이미지들의_정보를_비워두면_예외가_발생한다() throws Exception { + void 업로드_완료_하고자_하는_이미지들의_정보를_비워두면_예외가_발생한다() throws Exception { // given TempAlbumImagesUploadCompleteRequest request = new TempAlbumImagesUploadCompleteRequest(List.of()); @@ -2048,7 +2051,7 @@ class 임시_앨범_이미지_업로드_요청_시 { .andExpect(jsonPath("$.data.code").value("MethodArgumentNotValidException")) .andExpect( jsonPath("$.data.message") - .value("검증하고자 하는 임시 앨범 이미지들의 정보들은 비워둘 수 없습니다.")); + .value("업로드 완료 하고자 하는 임시 앨범 이미지들의 정보들은 비워둘 수 없습니다.")); } @Test @@ -2078,7 +2081,7 @@ class 임시_앨범_이미지_업로드_요청_시 { @NullSource @EmptySource @ValueSource(strings = {" "}) - void 검증_요청_이미지_url을_비워두면_예외가_발생한다(String imageUrl) throws Exception { + void 업로드_완료_요청_이미지_url을_비워두면_예외가_발생한다(String imageUrl) throws Exception { // given TempAlbumImagesUploadCompleteRequest request = new TempAlbumImagesUploadCompleteRequest( @@ -2099,7 +2102,7 @@ class 임시_앨범_이미지_업로드_요청_시 { .andExpect(jsonPath("$.data.code").value("MethodArgumentNotValidException")) .andExpect( jsonPath("$.data.message") - .value("검증하고자 하는 tempAlbumImageUrl은 비워둘 수 없습니다.")); + .value("업로드 완료 하고자 하는 tempAlbumImageUrl은 비워둘 수 없습니다.")); } } } diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java index 47fc5d15..a001022a 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java @@ -1191,7 +1191,7 @@ void setUp() { } @Nested - class 앨범_외_이미지_업로드를_검증할_때 { + class 앨범_외_이미지_업로드_완료_요청할_때 { @Test void 업로드_성공_시_예외가_발생하지_않는다() { @@ -1217,7 +1217,7 @@ class 앨범_외_이미지_업로드를_검증할_때 { } @Nested - class 앨범_이미지_업로드를_검증할_때 { + class 앨범_이미지_업로드_완료_요청할_때 { @BeforeEach void setUp() { @@ -1302,7 +1302,7 @@ void setUp() { } @Nested - class 임시_앨범_이미지_업로드를_검증할_때 { + class 임시_앨범_이미지_업로드_완료_요청할_때 { @BeforeEach void setUp() { From 5b146f1762ce3c9fbdfc598ffb11e5d39dd16812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Sat, 1 Nov 2025 16:11:05 +0900 Subject: [PATCH 13/16] =?UTF-8?q?fix:=20=EB=B3=B5=EC=88=98=ED=98=95=20?= =?UTF-8?q?=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../image/controller/ImageController.java | 16 +- ....java => AlbumImagesUploadUrlRequest.java} | 2 +- ...a => TempAlbumImagesUploadUrlRequest.java} | 2 +- ...java => AlbumImagesUploadUrlResponse.java} | 6 +- ... => TempAlbumImagesUploadUrlResponse.java} | 6 +- .../domain/image/service/ImageService.java | 8 +- .../image/service/ImageServiceImpl.java | 24 +-- .../image/controller/ImageControllerTest.java | 145 +++++++++--------- .../image/service/ImageServiceTest.java | 100 ++++++------ 9 files changed, 155 insertions(+), 154 deletions(-) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/{AlbumImageUploadUrlRequest.java => AlbumImagesUploadUrlRequest.java} (97%) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/{TempAlbumImageUploadUrlRequest.java => TempAlbumImagesUploadUrlRequest.java} (97%) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/{AlbumImageUploadUrlResponse.java => AlbumImagesUploadUrlResponse.java} (58%) rename cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/{TempAlbumImageUploadUrlResponse.java => TempAlbumImagesUploadUrlResponse.java} (57%) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java index be52c75f..79c1f236 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java @@ -64,13 +64,13 @@ public ResponseEntity nonAlbumImageUploadComplete( @Operation( summary = "앨범 이미지 업로드 Presigned URL들 생성", description = "앨범 이미지 업로드를 위한 Presigned URL들을 생성합니다.") - public AlbumImageUploadUrlResponse albumImageUploadUrlsCreate( - @PathVariable Long albumId, @Valid @RequestBody AlbumImageUploadUrlRequest request) { + public AlbumImagesUploadUrlResponse albumImageUploadUrlsCreate( + @PathVariable Long albumId, @Valid @RequestBody AlbumImagesUploadUrlRequest request) { return imageService.createAlbumImageUploadUrls(albumId, request); } @PostMapping("/albums/{albumId}/upload-complete") - @Operation(summary = "앨범 이미지 업로드 완료", description = "앨범 이미지들의 업로드를 완료합니다.") + @Operation(summary = "앨범 이미지들 업로드 완료", description = "앨범 이미지들의 업로드를 완료합니다.") public ResponseEntity albumImagesUploadComplete( @PathVariable Long albumId, @Valid @RequestBody AlbumImagesUploadCompleteRequest request) { @@ -123,16 +123,16 @@ public ResponseEntity albumImageDelete( @PostMapping("temp-albums/{tempAlbumId}/upload-url") @Operation( - summary = "임시 앨범 이미지 업로드 Presigned URL들 생성", - description = "임시 앨범 이미지 업로드를 위한 Presigned URL들을 생성합니다.") - public TempAlbumImageUploadUrlResponse tempAlbumImageUploadUrlsCreate( + summary = "임시 앨범 이미지들 업로드 Presigned URL들 생성", + description = "임시 앨범 이미지들 업로드를 위한 Presigned URL들을 생성합니다.") + public TempAlbumImagesUploadUrlResponse tempAlbumImageUploadUrlsCreate( @PathVariable Long tempAlbumId, - @Valid @RequestBody TempAlbumImageUploadUrlRequest request) { + @Valid @RequestBody TempAlbumImagesUploadUrlRequest request) { return imageService.createTempAlbumImageUploadUrls(tempAlbumId, request); } @PostMapping("/temp-albums/{tempAlbumId}/upload-complete") - @Operation(summary = "임시 앨범 이미지 업로드 완료", description = "임시 앨범 이미지들의 업로드를 완료합니다.") + @Operation(summary = "임시 앨범 이미지들 업로드 완료", description = "임시 앨범 이미지들의 업로드를 완료합니다.") public ResponseEntity tempAlbumImagesUploadComplete( @PathVariable Long tempAlbumId, @Valid @RequestBody TempAlbumImagesUploadCompleteRequest request) { diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadUrlRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesUploadUrlRequest.java similarity index 97% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadUrlRequest.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesUploadUrlRequest.java index 05bfa80f..3b3f642c 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImageUploadUrlRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/AlbumImagesUploadUrlRequest.java @@ -10,7 +10,7 @@ import org.cherrypic.global.annotation.Enum; import org.cherrypic.s3.enums.FileExtension; -public record AlbumImageUploadUrlRequest( +public record AlbumImagesUploadUrlRequest( @NotEmpty(message = "업로드할 피일들의 정보는 비워둘 수 없습니다.") @Valid @Schema(description = "업로드 요청 리스트") List payloads) { @Schema(name = "AlbumImageUploadRequestPayload") diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImageUploadUrlRequest.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesUploadUrlRequest.java similarity index 97% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImageUploadUrlRequest.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesUploadUrlRequest.java index 7c43f618..d8340209 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImageUploadUrlRequest.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/request/TempAlbumImagesUploadUrlRequest.java @@ -10,7 +10,7 @@ import org.cherrypic.global.annotation.Enum; import org.cherrypic.s3.enums.FileExtension; -public record TempAlbumImageUploadUrlRequest( +public record TempAlbumImagesUploadUrlRequest( @NotEmpty(message = "업로드할 피일들의 정보는 비워둘 수 없습니다.") @Valid @Schema(description = "업로드 요청 리스트") List payloads) { @Schema(name = "TempAlbumImageUploadRequestPayload") diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadUrlResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadUrlResponse.java similarity index 58% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadUrlResponse.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadUrlResponse.java index cfb2fff5..08f9d1c8 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImageUploadUrlResponse.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadUrlResponse.java @@ -3,9 +3,9 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; -public record AlbumImageUploadUrlResponse( +public record AlbumImagesUploadUrlResponse( @Schema(description = "생성된 presigned url 리스트", example = "[1,2,3,4]") List urls) { - public static AlbumImageUploadUrlResponse of(List urls) { - return new AlbumImageUploadUrlResponse(urls); + public static AlbumImagesUploadUrlResponse of(List urls) { + return new AlbumImagesUploadUrlResponse(urls); } } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadUrlResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesUploadUrlResponse.java similarity index 57% rename from cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadUrlResponse.java rename to cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesUploadUrlResponse.java index c19279fb..f20473a0 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImageUploadUrlResponse.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesUploadUrlResponse.java @@ -3,9 +3,9 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; -public record TempAlbumImageUploadUrlResponse( +public record TempAlbumImagesUploadUrlResponse( @Schema(description = "생성된 presigned url 리스트", example = "[1,2,3,4]") List urls) { - public static TempAlbumImageUploadUrlResponse of(List urls) { - return new TempAlbumImageUploadUrlResponse(urls); + public static TempAlbumImagesUploadUrlResponse of(List urls) { + return new TempAlbumImagesUploadUrlResponse(urls); } } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java index 4271a995..8dd5a86a 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java @@ -13,8 +13,8 @@ public interface ImageService { ImageUploadUrlResponse createEventCoverImageUploadUrl(ImageUploadUrlRequest request); - AlbumImageUploadUrlResponse createAlbumImageUploadUrls( - Long albumId, AlbumImageUploadUrlRequest request); + AlbumImagesUploadUrlResponse createAlbumImageUploadUrls( + Long albumId, AlbumImagesUploadUrlRequest request); SliceResponse getAlbumImages( Long albumId, @@ -32,8 +32,8 @@ SliceResponse getEventImages( void deleteAlbumImage(Long albumId, AlbumImageDeleteRequest request); - TempAlbumImageUploadUrlResponse createTempAlbumImageUploadUrls( - Long tempAlbumId, TempAlbumImageUploadUrlRequest request); + TempAlbumImagesUploadUrlResponse createTempAlbumImageUploadUrls( + Long tempAlbumId, TempAlbumImagesUploadUrlRequest request); void deleteTempAlbumImage(Long tempAlbumId, TempAlbumImageDeleteRequest request); diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java index e7928f07..637a68da 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java @@ -114,8 +114,8 @@ public ImageUploadUrlResponse createEventCoverImageUploadUrl(ImageUploadUrlReque } @Override - public AlbumImageUploadUrlResponse createAlbumImageUploadUrls( - Long albumId, AlbumImageUploadUrlRequest request) { + public AlbumImagesUploadUrlResponse createAlbumImageUploadUrls( + Long albumId, AlbumImagesUploadUrlRequest request) { final Member currentMember = memberUtil.getCurrentMember(); final Album album = getAlbumByIdWithLock(albumId); @@ -124,7 +124,7 @@ public AlbumImageUploadUrlResponse createAlbumImageUploadUrls( BigDecimal uploadCapacityMb = request.payloads().stream() - .map(AlbumImageUploadUrlRequest.Payload::capacityMb) + .map(AlbumImagesUploadUrlRequest.Payload::capacityMb) .reduce(BigDecimal.ZERO, BigDecimal::add); validateAlbumCapacity(album, uploadCapacityMb); @@ -141,7 +141,7 @@ public AlbumImageUploadUrlResponse createAlbumImageUploadUrls( req.md5Hashes())) .toList(); - return AlbumImageUploadUrlResponse.of(presignedUrls); + return AlbumImagesUploadUrlResponse.of(presignedUrls); } @Override @@ -207,8 +207,8 @@ public void deleteAlbumImage(Long albumId, AlbumImageDeleteRequest request) { @Override @Transactional - public TempAlbumImageUploadUrlResponse createTempAlbumImageUploadUrls( - Long tempAlbumId, TempAlbumImageUploadUrlRequest request) { + public TempAlbumImagesUploadUrlResponse createTempAlbumImageUploadUrls( + Long tempAlbumId, TempAlbumImagesUploadUrlRequest request) { final Member currentMember = memberUtil.getCurrentMember(); final TempAlbum tempAlbum = getTempAlbumById(tempAlbumId); @@ -216,7 +216,7 @@ public TempAlbumImageUploadUrlResponse createTempAlbumImageUploadUrls( BigDecimal uploadCapacityMb = request.payloads().stream() - .map(TempAlbumImageUploadUrlRequest.Payload::capacityMb) + .map(TempAlbumImagesUploadUrlRequest.Payload::capacityMb) .reduce(BigDecimal.ZERO, BigDecimal::add); validateTempAlbumCapacity(tempAlbum, uploadCapacityMb); @@ -233,7 +233,7 @@ public TempAlbumImageUploadUrlResponse createTempAlbumImageUploadUrls( req.md5Hashes())) .toList(); - return TempAlbumImageUploadUrlResponse.of(presignedUrls); + return TempAlbumImagesUploadUrlResponse.of(presignedUrls); } @Override @@ -435,10 +435,10 @@ private void validateTempAlbumCapacity(TempAlbum tempAlbum, BigDecimal uploadCap } } - private void validateDistinctHashes(AlbumImageUploadUrlRequest request) { + private void validateDistinctHashes(AlbumImagesUploadUrlRequest request) { List hashes = request.payloads().stream() - .map(AlbumImageUploadUrlRequest.Payload::md5Hashes) + .map(AlbumImagesUploadUrlRequest.Payload::md5Hashes) .toList(); if (hashes.stream().distinct().count() != hashes.size()) { @@ -446,10 +446,10 @@ private void validateDistinctHashes(AlbumImageUploadUrlRequest request) { } } - private void validateDistinctHashes(TempAlbumImageUploadUrlRequest request) { + private void validateDistinctHashes(TempAlbumImagesUploadUrlRequest request) { List hashes = request.payloads().stream() - .map(TempAlbumImageUploadUrlRequest.Payload::md5Hashes) + .map(TempAlbumImagesUploadUrlRequest.Payload::md5Hashes) .toList(); if (hashes.stream().distinct().count() != hashes.size()) { diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index 473bcb4c..e07736d6 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -348,16 +348,16 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 유효한_요청이면_이미지_업로드_Presigned_URL들을_반환한다() throws Exception { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); - AlbumImageUploadUrlResponse response = - new AlbumImageUploadUrlResponse( + AlbumImagesUploadUrlResponse response = + new AlbumImagesUploadUrlResponse( List.of("testPresignedUrl1", "testPresignedUrl2")); given(imageService.createAlbumImageUploadUrls(1L, request)).willReturn(response); @@ -378,12 +378,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 앨범이_존재하지_않는_경우_예외가_발생한다() throws Exception { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) @@ -406,12 +406,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 앨범에_속하지_않은_사용자가_앨범_이미지_업로드_URL을_요청하면_예외가_발생한다() throws Exception { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) @@ -434,12 +434,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void LIMITED_권한의_사용자가_앨범_이미지_업로드_URL을_요청하면_예외가_발생한다() throws Exception { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) @@ -462,12 +462,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 구독이_만료된_앨범인_경우_예외가_발생한다() throws Exception { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) @@ -491,12 +491,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 앨범의_남은_용량을_초과해서_요청하면_예외가_발생한다() throws Exception { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) @@ -519,12 +519,12 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void MD5_해시에_중복된_값이_존재하면_예외가_발생한다() throws Exception { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash", BigDecimal.ONE), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash", BigDecimal.ONE))); given(imageService.createAlbumImageUploadUrls(1L, request)) @@ -550,10 +550,10 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @ValueSource(strings = {"JPEG1", "PDF", "TXT"}) void 파일_확장자가_null_또는_지원하지_않는_형식이면_예외가_발생한다(String extension) throws Exception { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.from(extension), "testMd5Hash1", BigDecimal.ONE))); @@ -578,10 +578,10 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 이미지_용량을_비워두면_예외가_발생한다() throws Exception { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash", null))); // when & then @@ -604,10 +604,10 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @ValueSource(strings = {" "}) void MD5_해시가_null_또는_공백이면_예외가_발생한다(String md5Hash) throws Exception { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, md5Hash, BigDecimal.ONE))); // when & then @@ -627,7 +627,7 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 업로드_요청_정보를_비워두면_예외가_발생한다() throws Exception { // given - AlbumImageUploadUrlRequest request = new AlbumImageUploadUrlRequest(List.of()); + AlbumImagesUploadUrlRequest request = new AlbumImagesUploadUrlRequest(List.of()); // when & then ResultActions perform = @@ -1343,20 +1343,20 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 유효한_요청이면_임시_앨범_이미지_업로드_Presigned_URL들을_반환한다() throws Exception { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", new BigDecimal("0.3")), - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", new BigDecimal("0.3")))); - TempAlbumImageUploadUrlResponse response = - new TempAlbumImageUploadUrlResponse( + TempAlbumImagesUploadUrlResponse response = + new TempAlbumImagesUploadUrlResponse( List.of("testPresignedUrl1", "testPresignedUrl2")); given(imageService.createTempAlbumImageUploadUrls(1L, request)).willReturn(response); @@ -1377,14 +1377,14 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 임시_앨범이_존재하지_않는_경우_예외가_발생한다() throws Exception { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", new BigDecimal("0.3")), - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", new BigDecimal("0.3")))); @@ -1409,14 +1409,14 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 임시_앨범_소유자가_아닌_사용자가_앨범_이미지_업로드_URL을_요청하면_예외가_발생한다() throws Exception { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", new BigDecimal("0.3")), - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", new BigDecimal("0.3")))); @@ -1441,14 +1441,14 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 임시_앨범의_남은_용량을_초과해서_요청하면_예외가_발생한다() throws Exception { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", TempAlbumType.DEFAULT.getCapacityMb()), - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given(imageService.createTempAlbumImageUploadUrls(1L, request)) @@ -1472,14 +1472,14 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void MD5_해시에_중복된_값이_존재하면_예외가_발생한다() throws Exception { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", new BigDecimal("0.3")), - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", new BigDecimal("0.3")))); @@ -1507,10 +1507,10 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @ValueSource(strings = {"JPEG1", "PDF", "TXT"}) void 파일_확장자가_null_또는_지원하지_않는_형식이면_예외가_발생한다(String extension) throws Exception { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.from(extension), "testMd5Hash1", BigDecimal.ONE))); @@ -1535,10 +1535,10 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 이미지_용량을_비워두면_예외가_발생한다() throws Exception { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash", null))); // when & then @@ -1561,10 +1561,10 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @ValueSource(strings = {" "}) void MD5_해시가_null_또는_공백이면_예외가_발생한다(String md5Hash) throws Exception { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, md5Hash, BigDecimal.ONE))); // when & then @@ -1584,7 +1584,8 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { @Test void 업로드_요청_정보를_비워두면_예외가_발생한다() throws Exception { // given - TempAlbumImageUploadUrlRequest request = new TempAlbumImageUploadUrlRequest(List.of()); + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest(List.of()); // when & then ResultActions perform = diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java index a001022a..1628e504 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java @@ -312,12 +312,12 @@ void setUp() { @Test void 유효한_요청이면_Presigned_URL들을_반환한다() { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); given( s3Util.createPresignedUrl( @@ -346,7 +346,7 @@ void setUp() { + "&Content-MD5=testMd5Hash2"); // when - AlbumImageUploadUrlResponse response = + AlbumImagesUploadUrlResponse response = imageService.createAlbumImageUploadUrls(1L, request); // then @@ -368,12 +368,12 @@ void setUp() { @Test void 앨범이_존재하지_않는_경우_예외가_발생한다() { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then @@ -385,12 +385,12 @@ void setUp() { @Test void 앨범에_속하지_않은_사용자가_앨범_이미지_업로드_URL을_요청하면_예외가_발생한다() { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then @@ -402,12 +402,12 @@ void setUp() { @Test void LIMITED_권한의_사용자가_앨범_이미지_업로드_URL을_요청하면_예외가_발생한다() { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then @@ -419,12 +419,12 @@ void setUp() { @Test void 구독이_만료된_앨범인_경우_예외가_발생한다() { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ONE), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then @@ -436,14 +436,14 @@ void setUp() { @Test void 앨범의_남은_용량을_초과해서_요청하면_예외가_발생한다() { /// given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", AlbumType.BASIC.getCapacityMb()), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then @@ -455,12 +455,12 @@ void setUp() { @Test void 해시값에_중복이_존재하면_예외가_발생한다() { // given - AlbumImageUploadUrlRequest request = - new AlbumImageUploadUrlRequest( + AlbumImagesUploadUrlRequest request = + new AlbumImagesUploadUrlRequest( List.of( - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO), - new AlbumImageUploadUrlRequest.Payload( + new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO))); // when & then assertThatThrownBy(() -> imageService.createAlbumImageUploadUrls(1L, request)) @@ -964,14 +964,14 @@ void setUp() { @Test void 유효한_요청이면_Presigned_URL들을_반환한다() { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", new BigDecimal("0.3")), - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", new BigDecimal("0.3")))); @@ -1002,7 +1002,7 @@ void setUp() { + "&Content-MD5=testMd5Hash2"); // when - TempAlbumImageUploadUrlResponse response = + TempAlbumImagesUploadUrlResponse response = imageService.createTempAlbumImageUploadUrls(1L, request); // then @@ -1024,12 +1024,12 @@ void setUp() { @Test void 임시_앨범이_존재하지_않는_경우_예외가_발생한다() { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO), - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ZERO))); // when & then @@ -1041,12 +1041,12 @@ void setUp() { @Test void 임시_앨범의_소유자가_아닌_사람이_이미지_업로드를_시도하면_예외가_발생한다() { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO), - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ZERO))); // when & then @@ -1058,14 +1058,14 @@ void setUp() { @Test void 임시_앨범의_남은_용량을_초과해서_요청하면_예외가_발생한다() { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", TempAlbumType.DEFAULT.getCapacityMb()), - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); // when & then @@ -1077,12 +1077,12 @@ void setUp() { @Test void 해시값에_중복이_존재하면_예외가_발생한다() { // given - TempAlbumImageUploadUrlRequest request = - new TempAlbumImageUploadUrlRequest( + TempAlbumImagesUploadUrlRequest request = + new TempAlbumImagesUploadUrlRequest( List.of( - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO), - new TempAlbumImageUploadUrlRequest.Payload( + new TempAlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash1", BigDecimal.ZERO))); // when & then assertThatThrownBy(() -> imageService.createTempAlbumImageUploadUrls(1L, request)) From 0d5bdd0d706a0ddc0f48d62f87964a46e21d5f9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Sat, 1 Nov 2025 16:17:44 +0900 Subject: [PATCH 14/16] =?UTF-8?q?fix:=20=EB=A1=9C=EC=BB=AC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=97=AC=EB=B6=80=20=ED=95=84=EB=93=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/AlbumImagesUploadCompleteResponse.java | 6 ++---- .../cherrypic/domain/image/service/ImageServiceImpl.java | 3 +-- .../org/cherrypic/image/controller/ImageControllerTest.java | 3 +-- .../java/org/cherrypic/image/service/ImageServiceTest.java | 1 - 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadCompleteResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadCompleteResponse.java index 2a5f33ff..0868b9d1 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadCompleteResponse.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadCompleteResponse.java @@ -4,10 +4,8 @@ import java.util.List; public record AlbumImagesUploadCompleteResponse( - @Schema(description = "로컬 사진 삭제 허용 여부") Boolean localImageDeletion, @Schema(description = "생성된 이미지들의 ID 리스트") List imageIds) { - public static AlbumImagesUploadCompleteResponse of( - List imageIds, Boolean localImageDeletion) { - return new AlbumImagesUploadCompleteResponse(localImageDeletion, imageIds); + public static AlbumImagesUploadCompleteResponse of(List imageIds) { + return new AlbumImagesUploadCompleteResponse(imageIds); } } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java index 637a68da..ec5bbf36 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java @@ -317,8 +317,7 @@ public AlbumImagesUploadCompleteResponse completeAlbumImagesUpload( imageRepository.findImageIdsByUrlsInOrder( images.stream().map(Image::getUrl).toList()); - return AlbumImagesUploadCompleteResponse.of( - imageIds, currentMember.getLocalImageDeletion()); + return AlbumImagesUploadCompleteResponse.of(imageIds); } @Override diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index e07736d6..e56c8e7f 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -1798,7 +1798,7 @@ class 앨범_이미지_업로드_요청_시 { LocalDateTime.now(), BigDecimal.ONE, "testImageUrl2"))); AlbumImagesUploadCompleteResponse response = - new AlbumImagesUploadCompleteResponse(false, List.of(1L, 2L)); + new AlbumImagesUploadCompleteResponse(List.of(1L, 2L)); given(imageService.completeAlbumImagesUpload(1L, request)).willReturn(response); @@ -1812,7 +1812,6 @@ class 앨범_이미지_업로드_요청_시 { perform.andExpect(status().isCreated()) .andExpect(jsonPath("$.success").value(true)) .andExpect(jsonPath("$.status").value(HttpStatus.CREATED.value())) - .andExpect(jsonPath("$.data.localImageDeletion").value(false)) .andExpect(jsonPath("$.data.imageIds").value(Matchers.contains(1, 2))); } diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java index 1628e504..3a1420a4 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java @@ -1257,7 +1257,6 @@ void setUp() { // then Assertions.assertAll( - () -> assertThat(response.localImageDeletion()).isFalse(), () -> assertThat(response.imageIds()).isEqualTo(List.of(1L, 2L)), () -> assertThat(imageRepository.findAllById(List.of(1L, 2L)).size()) From 366112eaa9567ec43b8cab42cc5fdf070834980f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Sat, 1 Nov 2025 20:02:14 +0900 Subject: [PATCH 15/16] =?UTF-8?q?refactor:=20=EB=AA=85=EB=AA=85=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/image/controller/ImageController.java | 4 ++-- .../dto/response/AlbumImagesPresignedUrlResponse.java | 11 +++++++++++ .../dto/response/AlbumImagesUploadUrlResponse.java | 11 ----------- .../response/TempAlbumImagesPresignedUrlResponse.java | 11 +++++++++++ .../response/TempAlbumImagesUploadUrlResponse.java | 11 ----------- .../cherrypic/domain/image/service/ImageService.java | 4 ++-- .../domain/image/service/ImageServiceImpl.java | 8 ++++---- .../image/controller/ImageControllerTest.java | 8 ++++---- .../org/cherrypic/image/service/ImageServiceTest.java | 4 ++-- 9 files changed, 36 insertions(+), 36 deletions(-) create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesPresignedUrlResponse.java delete mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadUrlResponse.java create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesPresignedUrlResponse.java delete mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesUploadUrlResponse.java diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java index 79c1f236..3d9feb5a 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java @@ -64,7 +64,7 @@ public ResponseEntity nonAlbumImageUploadComplete( @Operation( summary = "앨범 이미지 업로드 Presigned URL들 생성", description = "앨범 이미지 업로드를 위한 Presigned URL들을 생성합니다.") - public AlbumImagesUploadUrlResponse albumImageUploadUrlsCreate( + public AlbumImagesPresignedUrlResponse albumImageUploadUrlsCreate( @PathVariable Long albumId, @Valid @RequestBody AlbumImagesUploadUrlRequest request) { return imageService.createAlbumImageUploadUrls(albumId, request); } @@ -125,7 +125,7 @@ public ResponseEntity albumImageDelete( @Operation( summary = "임시 앨범 이미지들 업로드 Presigned URL들 생성", description = "임시 앨범 이미지들 업로드를 위한 Presigned URL들을 생성합니다.") - public TempAlbumImagesUploadUrlResponse tempAlbumImageUploadUrlsCreate( + public TempAlbumImagesPresignedUrlResponse tempAlbumImageUploadUrlsCreate( @PathVariable Long tempAlbumId, @Valid @RequestBody TempAlbumImagesUploadUrlRequest request) { return imageService.createTempAlbumImageUploadUrls(tempAlbumId, request); diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesPresignedUrlResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesPresignedUrlResponse.java new file mode 100644 index 00000000..53a62e12 --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesPresignedUrlResponse.java @@ -0,0 +1,11 @@ +package org.cherrypic.domain.image.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; + +public record AlbumImagesPresignedUrlResponse( + @Schema(description = "생성된 presigned url 리스트") List urls) { + public static AlbumImagesPresignedUrlResponse of(List urls) { + return new AlbumImagesPresignedUrlResponse(urls); + } +} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadUrlResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadUrlResponse.java deleted file mode 100644 index 08f9d1c8..00000000 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/AlbumImagesUploadUrlResponse.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.cherrypic.domain.image.dto.response; - -import io.swagger.v3.oas.annotations.media.Schema; -import java.util.List; - -public record AlbumImagesUploadUrlResponse( - @Schema(description = "생성된 presigned url 리스트", example = "[1,2,3,4]") List urls) { - public static AlbumImagesUploadUrlResponse of(List urls) { - return new AlbumImagesUploadUrlResponse(urls); - } -} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesPresignedUrlResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesPresignedUrlResponse.java new file mode 100644 index 00000000..11ff0e05 --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesPresignedUrlResponse.java @@ -0,0 +1,11 @@ +package org.cherrypic.domain.image.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; + +public record TempAlbumImagesPresignedUrlResponse( + @Schema(description = "생성된 presigned url 리스트") List urls) { + public static TempAlbumImagesPresignedUrlResponse of(List urls) { + return new TempAlbumImagesPresignedUrlResponse(urls); + } +} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesUploadUrlResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesUploadUrlResponse.java deleted file mode 100644 index f20473a0..00000000 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/TempAlbumImagesUploadUrlResponse.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.cherrypic.domain.image.dto.response; - -import io.swagger.v3.oas.annotations.media.Schema; -import java.util.List; - -public record TempAlbumImagesUploadUrlResponse( - @Schema(description = "생성된 presigned url 리스트", example = "[1,2,3,4]") List urls) { - public static TempAlbumImagesUploadUrlResponse of(List urls) { - return new TempAlbumImagesUploadUrlResponse(urls); - } -} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java index 8dd5a86a..d0b0ea92 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java @@ -13,7 +13,7 @@ public interface ImageService { ImageUploadUrlResponse createEventCoverImageUploadUrl(ImageUploadUrlRequest request); - AlbumImagesUploadUrlResponse createAlbumImageUploadUrls( + AlbumImagesPresignedUrlResponse createAlbumImageUploadUrls( Long albumId, AlbumImagesUploadUrlRequest request); SliceResponse getAlbumImages( @@ -32,7 +32,7 @@ SliceResponse getEventImages( void deleteAlbumImage(Long albumId, AlbumImageDeleteRequest request); - TempAlbumImagesUploadUrlResponse createTempAlbumImageUploadUrls( + TempAlbumImagesPresignedUrlResponse createTempAlbumImageUploadUrls( Long tempAlbumId, TempAlbumImagesUploadUrlRequest request); void deleteTempAlbumImage(Long tempAlbumId, TempAlbumImageDeleteRequest request); diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java index ec5bbf36..6b2df8c0 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java @@ -114,7 +114,7 @@ public ImageUploadUrlResponse createEventCoverImageUploadUrl(ImageUploadUrlReque } @Override - public AlbumImagesUploadUrlResponse createAlbumImageUploadUrls( + public AlbumImagesPresignedUrlResponse createAlbumImageUploadUrls( Long albumId, AlbumImagesUploadUrlRequest request) { final Member currentMember = memberUtil.getCurrentMember(); final Album album = getAlbumByIdWithLock(albumId); @@ -141,7 +141,7 @@ public AlbumImagesUploadUrlResponse createAlbumImageUploadUrls( req.md5Hashes())) .toList(); - return AlbumImagesUploadUrlResponse.of(presignedUrls); + return AlbumImagesPresignedUrlResponse.of(presignedUrls); } @Override @@ -207,7 +207,7 @@ public void deleteAlbumImage(Long albumId, AlbumImageDeleteRequest request) { @Override @Transactional - public TempAlbumImagesUploadUrlResponse createTempAlbumImageUploadUrls( + public TempAlbumImagesPresignedUrlResponse createTempAlbumImageUploadUrls( Long tempAlbumId, TempAlbumImagesUploadUrlRequest request) { final Member currentMember = memberUtil.getCurrentMember(); final TempAlbum tempAlbum = getTempAlbumById(tempAlbumId); @@ -233,7 +233,7 @@ public TempAlbumImagesUploadUrlResponse createTempAlbumImageUploadUrls( req.md5Hashes())) .toList(); - return TempAlbumImagesUploadUrlResponse.of(presignedUrls); + return TempAlbumImagesPresignedUrlResponse.of(presignedUrls); } @Override diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index e56c8e7f..b04a6594 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -356,8 +356,8 @@ class 앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { new AlbumImagesUploadUrlRequest.Payload( FileExtension.JPEG, "testMd5Hash2", BigDecimal.ONE))); - AlbumImagesUploadUrlResponse response = - new AlbumImagesUploadUrlResponse( + AlbumImagesPresignedUrlResponse response = + new AlbumImagesPresignedUrlResponse( List.of("testPresignedUrl1", "testPresignedUrl2")); given(imageService.createAlbumImageUploadUrls(1L, request)).willReturn(response); @@ -1355,8 +1355,8 @@ class 임시_앨범_이미지_업로드_Presigned_URL을_생성_요청_시 { "testMd5Hash2", new BigDecimal("0.3")))); - TempAlbumImagesUploadUrlResponse response = - new TempAlbumImagesUploadUrlResponse( + TempAlbumImagesPresignedUrlResponse response = + new TempAlbumImagesPresignedUrlResponse( List.of("testPresignedUrl1", "testPresignedUrl2")); given(imageService.createTempAlbumImageUploadUrls(1L, request)).willReturn(response); diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java index 3a1420a4..7694e939 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java @@ -346,7 +346,7 @@ void setUp() { + "&Content-MD5=testMd5Hash2"); // when - AlbumImagesUploadUrlResponse response = + AlbumImagesPresignedUrlResponse response = imageService.createAlbumImageUploadUrls(1L, request); // then @@ -1002,7 +1002,7 @@ void setUp() { + "&Content-MD5=testMd5Hash2"); // when - TempAlbumImagesUploadUrlResponse response = + TempAlbumImagesPresignedUrlResponse response = imageService.createTempAlbumImageUploadUrls(1L, request); // then From c82baa0b1b81f5aa96c1240a61b4e2e7422d5273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9A=A9=EC=A4=80?= <141994188+youngJun99@users.noreply.github.com> Date: Sat, 1 Nov 2025 20:50:10 +0900 Subject: [PATCH 16/16] =?UTF-8?q?refactor:=20=EB=AA=85=EB=AA=85=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/image/controller/ImageController.java | 6 +++--- .../dto/response/ImagePresignedUrlResponse.java | 10 ++++++++++ .../image/dto/response/ImageUploadUrlResponse.java | 9 --------- .../domain/image/service/ImageService.java | 6 +++--- .../domain/image/service/ImageServiceImpl.java | 13 +++++++------ .../image/controller/ImageControllerTest.java | 6 +++--- .../cherrypic/image/service/ImageServiceTest.java | 8 +++++--- 7 files changed, 31 insertions(+), 27 deletions(-) create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImagePresignedUrlResponse.java delete mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImageUploadUrlResponse.java diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java index 3d9feb5a..bf14f893 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/controller/ImageController.java @@ -29,7 +29,7 @@ public class ImageController { @Operation( summary = "회원 프로필 이미지 Presigned URL 생성", description = "회원 프로필 이미지 업로드를 위한 Presigned URL을 생성합니다.") - public ImageUploadUrlResponse memberProfileImageUploadUrlCreate( + public ImagePresignedUrlResponse memberProfileImageUploadUrlCreate( @Valid @RequestBody ImageUploadUrlRequest request) { return imageService.createMemberProfileImageUploadUrl(request); } @@ -38,7 +38,7 @@ public ImageUploadUrlResponse memberProfileImageUploadUrlCreate( @Operation( summary = "앨범 커버 이미지 Presigned URL 생성", description = "앨범 커버 이미지 업로드를 위한 Presigned URL을 생성합니다.") - public ImageUploadUrlResponse albumCoverImageUploadUrlCreate( + public ImagePresignedUrlResponse albumCoverImageUploadUrlCreate( @Valid @RequestBody ImageUploadUrlRequest request) { return imageService.createAlbumCoverImageUploadUrl(request); } @@ -47,7 +47,7 @@ public ImageUploadUrlResponse albumCoverImageUploadUrlCreate( @Operation( summary = "이벤트 커버 이미지 Presigned URL 생성", description = "이벤트 커버 이미지 업로드를 위한 Presigned URL을 생성합니다.") - public ImageUploadUrlResponse eventCoverImageUploadUrlCreate( + public ImagePresignedUrlResponse eventCoverImageUploadUrlCreate( @Valid @RequestBody ImageUploadUrlRequest request) { return imageService.createEventCoverImageUploadUrl(request); } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImagePresignedUrlResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImagePresignedUrlResponse.java new file mode 100644 index 00000000..9712c0f2 --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImagePresignedUrlResponse.java @@ -0,0 +1,10 @@ +package org.cherrypic.domain.image.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; + +public record ImagePresignedUrlResponse( + @Schema(description = "Presigned URL") String presignedUrl) { + public static ImagePresignedUrlResponse of(String presignedUrl) { + return new ImagePresignedUrlResponse(presignedUrl); + } +} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImageUploadUrlResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImageUploadUrlResponse.java deleted file mode 100644 index c84516c1..00000000 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/dto/response/ImageUploadUrlResponse.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.cherrypic.domain.image.dto.response; - -import io.swagger.v3.oas.annotations.media.Schema; - -public record ImageUploadUrlResponse(@Schema(description = "Presigned URL") String presignedUrl) { - public static ImageUploadUrlResponse of(String presignedUrl) { - return new ImageUploadUrlResponse(presignedUrl); - } -} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java index d0b0ea92..38b9a7dc 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageService.java @@ -7,11 +7,11 @@ import org.cherrypic.global.pagination.SortParameter; public interface ImageService { - ImageUploadUrlResponse createMemberProfileImageUploadUrl(ImageUploadUrlRequest request); + ImagePresignedUrlResponse createMemberProfileImageUploadUrl(ImageUploadUrlRequest request); - ImageUploadUrlResponse createAlbumCoverImageUploadUrl(ImageUploadUrlRequest request); + ImagePresignedUrlResponse createAlbumCoverImageUploadUrl(ImageUploadUrlRequest request); - ImageUploadUrlResponse createEventCoverImageUploadUrl(ImageUploadUrlRequest request); + ImagePresignedUrlResponse createEventCoverImageUploadUrl(ImageUploadUrlRequest request); AlbumImagesPresignedUrlResponse createAlbumImageUploadUrls( Long albumId, AlbumImagesUploadUrlRequest request); diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java index 6b2df8c0..d7efd006 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/image/service/ImageServiceImpl.java @@ -66,7 +66,8 @@ public class ImageServiceImpl implements ImageService { private final ApplicationEventPublisher eventPublisher; @Override - public ImageUploadUrlResponse createMemberProfileImageUploadUrl(ImageUploadUrlRequest request) { + public ImagePresignedUrlResponse createMemberProfileImageUploadUrl( + ImageUploadUrlRequest request) { final Member currentMember = memberUtil.getCurrentMember(); validateImageExtension(request.fileExtension()); @@ -78,11 +79,11 @@ public ImageUploadUrlResponse createMemberProfileImageUploadUrl(ImageUploadUrlRe request.fileExtension(), request.md5Hash()); - return ImageUploadUrlResponse.of(presignedUrl); + return ImagePresignedUrlResponse.of(presignedUrl); } @Override - public ImageUploadUrlResponse createAlbumCoverImageUploadUrl(ImageUploadUrlRequest request) { + public ImagePresignedUrlResponse createAlbumCoverImageUploadUrl(ImageUploadUrlRequest request) { final Member currentMember = memberUtil.getCurrentMember(); validateImageExtension(request.fileExtension()); @@ -94,11 +95,11 @@ public ImageUploadUrlResponse createAlbumCoverImageUploadUrl(ImageUploadUrlReque request.fileExtension(), request.md5Hash()); - return ImageUploadUrlResponse.of(presignedUrl); + return ImagePresignedUrlResponse.of(presignedUrl); } @Override - public ImageUploadUrlResponse createEventCoverImageUploadUrl(ImageUploadUrlRequest request) { + public ImagePresignedUrlResponse createEventCoverImageUploadUrl(ImageUploadUrlRequest request) { final Member currentMember = memberUtil.getCurrentMember(); validateImageExtension(request.fileExtension()); @@ -110,7 +111,7 @@ public ImageUploadUrlResponse createEventCoverImageUploadUrl(ImageUploadUrlReque request.fileExtension(), request.md5Hash()); - return ImageUploadUrlResponse.of(presignedUrl); + return ImagePresignedUrlResponse.of(presignedUrl); } @Override diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java index b04a6594..34849112 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/controller/ImageControllerTest.java @@ -57,7 +57,7 @@ class 프로필용_Presigned_URL_생성_요청_시 { ImageUploadUrlRequest request = new ImageUploadUrlRequest(FileExtension.JPEG, "testMd5Hash"); - ImageUploadUrlResponse response = new ImageUploadUrlResponse("testPresignedUrl"); + ImagePresignedUrlResponse response = new ImagePresignedUrlResponse("testPresignedUrl"); given(imageService.createMemberProfileImageUploadUrl(request)).willReturn(response); @@ -155,7 +155,7 @@ class 앨범_커버용_Presigned_URL_생성_요청_시 { ImageUploadUrlRequest request = new ImageUploadUrlRequest(FileExtension.JPEG, "testMd5Hash"); - ImageUploadUrlResponse response = new ImageUploadUrlResponse("testPresignedUrl"); + ImagePresignedUrlResponse response = new ImagePresignedUrlResponse("testPresignedUrl"); given(imageService.createAlbumCoverImageUploadUrl(request)).willReturn(response); @@ -253,7 +253,7 @@ class 이벤트_커버용_Presigned_URL_생성_요청_시 { ImageUploadUrlRequest request = new ImageUploadUrlRequest(FileExtension.JPEG, "testMd5Hash"); - ImageUploadUrlResponse response = new ImageUploadUrlResponse("testPresignedUrl"); + ImagePresignedUrlResponse response = new ImagePresignedUrlResponse("testPresignedUrl"); given(imageService.createEventCoverImageUploadUrl(request)).willReturn(response); diff --git a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java index 7694e939..55968108 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/image/service/ImageServiceTest.java @@ -115,7 +115,7 @@ void setUp() { + " + \"&Content-MD5=testMd5Hash\""); // when - ImageUploadUrlResponse response = + ImagePresignedUrlResponse response = imageService.createMemberProfileImageUploadUrl(request); // then @@ -183,7 +183,8 @@ void setUp() { + "&Content-MD5=testMd5Hash"); // when - ImageUploadUrlResponse response = imageService.createAlbumCoverImageUploadUrl(request); + ImagePresignedUrlResponse response = + imageService.createAlbumCoverImageUploadUrl(request); // then assertThat(response.presignedUrl()) @@ -254,7 +255,8 @@ void setUp() { + "&Content-MD5=testMd5Hash"); // when - ImageUploadUrlResponse response = imageService.createEventCoverImageUploadUrl(request); + ImagePresignedUrlResponse response = + imageService.createEventCoverImageUploadUrl(request); // then assertThat(response.presignedUrl())