From f0cbc378344d0319b05e21dea00fecad49007b5e Mon Sep 17 00:00:00 2001 From: JuHyuk Lim Date: Fri, 16 May 2025 12:25:46 +0900 Subject: [PATCH 01/14] feat: Font Validation --- .../fontory/fontorybe/font/controller/FontController.java | 5 ++--- .../fontorybe/font/controller/dto/FontCreateDTO.java | 3 +++ .../font/controller/dto/FontProgressUpdateDTO.java | 4 +++- .../fontorybe/font/controller/dto/FontUpdateDTO.java | 7 +++++++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/fontory/fontorybe/font/controller/FontController.java b/src/main/java/org/fontory/fontorybe/font/controller/FontController.java index e99fe3c..7a09e43 100644 --- a/src/main/java/org/fontory/fontorybe/font/controller/FontController.java +++ b/src/main/java/org/fontory/fontorybe/font/controller/FontController.java @@ -30,7 +30,6 @@ import org.fontory.fontorybe.font.controller.port.FontService; import org.fontory.fontorybe.font.domain.Font; import org.springframework.data.domain.Page; -import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -124,7 +123,7 @@ public ResponseEntity getFontProgress(@Login UserPrincipal userPrincipal) { @Parameter(name = "fontId", description = "수정할 폰트 ID") @PutMapping("/{fontId}") public ResponseEntity updateFont( - @RequestBody FontUpdateDTO fontUpdateDTO, + @RequestBody @Valid FontUpdateDTO fontUpdateDTO, @PathVariable Long fontId, @Login UserPrincipal userPrincipal ) { @@ -260,7 +259,7 @@ public ResponseEntity getPopularFonts(@Login(required = false) UserPrincipal @Parameter(name = "fontId", description = "수정할 폰트 ID") @PatchMapping("/progress/{fontId}") public ResponseEntity updateFontProgress( - @RequestBody FontProgressUpdateDTO fontProgressUpdateDTO, + @RequestBody @Valid FontProgressUpdateDTO fontProgressUpdateDTO, @PathVariable Long fontId ) { log.info("Request received: Update font progress ID: {}, request: {}", diff --git a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java index 01a1a91..2cc153d 100644 --- a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java +++ b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java @@ -2,6 +2,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -12,9 +13,11 @@ public class FontCreateDTO { @NotBlank(message = "폰트 이름은 필수 입력 값입니다.") + @Size(min = 2, max = 30, message = "폰트 이름은 2자 이상 30자 이하로 입력해주세요.") private String name; @NotBlank(message = "폰트 예시는 필수 입력 값입니다.") + @Size(min = 10, max = 255, message = "폰트 예시는 10자 이상 255자 이하로 입력해주세요.") private String example; @Pattern(regexp = "^$|^01[016-9]\\d{7,8}$", message = "휴대폰 번호 형식이 올바르지 않습니다.") diff --git a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontProgressUpdateDTO.java b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontProgressUpdateDTO.java index 2a26840..dbd43e5 100644 --- a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontProgressUpdateDTO.java +++ b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontProgressUpdateDTO.java @@ -1,6 +1,7 @@ package org.fontory.fontorybe.font.controller.dto; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import lombok.Builder; import lombok.Getter; import org.fontory.fontorybe.font.infrastructure.entity.FontStatus; @@ -8,6 +9,7 @@ @Getter @Builder public class FontProgressUpdateDTO { - @Schema(description = "폰트의 상태 (PROGRESS, DONE)") + @NotNull(message = "폰트 상태는 필수입니다.") + @Schema(description = "폰트의 상태 (PROGRESS, DONE, FAILED)") private FontStatus status; } diff --git a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontUpdateDTO.java b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontUpdateDTO.java index 3e01b08..81a373e 100644 --- a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontUpdateDTO.java +++ b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontUpdateDTO.java @@ -1,11 +1,18 @@ package org.fontory.fontorybe.font.controller.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; import lombok.Builder; import lombok.Getter; @Getter @Builder public class FontUpdateDTO { + @NotBlank(message = "폰트 이름은 필수 입력 값입니다.") + @Size(min = 2, max = 30, message = "폰트 이름은 2자 이상 30자 이하로 입력해주세요.") private String name; + + @NotBlank(message = "폰트 예시는 필수 입력 값입니다.") + @Size(min = 10, max = 255, message = "폰트 예시는 10자 이상 255자 이하로 입력해주세요.") private String example; } From 0bb4eec6b252279e2405dbb5e750e294299e610c Mon Sep 17 00:00:00 2001 From: JuHyuk Lim Date: Fri, 16 May 2025 12:35:35 +0900 Subject: [PATCH 02/14] feat: Member Validation --- .../member/controller/ProfileController.java | 3 ++- .../member/controller/RegistrationController.java | 3 ++- .../controller/dto/InitMemberInfoRequest.java | 13 +++++++++++++ .../member/controller/dto/MemberUpdateRequest.java | 7 +++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java b/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java index b651cee..ab095e6 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java @@ -3,6 +3,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; import lombok.Builder; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -71,7 +72,7 @@ public ResponseEntity getMyProfile( @PatchMapping(consumes = MULTIPART_FORM_DATA_VALUE) public ResponseEntity updateMember( @Login UserPrincipal userPrincipal, - @RequestPart MemberUpdateRequest req, + @RequestPart @Valid MemberUpdateRequest req, @SingleFileUpload @RequestPart("file") List files ) { Long requestMemberId = userPrincipal.getId(); diff --git a/src/main/java/org/fontory/fontorybe/member/controller/RegistrationController.java b/src/main/java/org/fontory/fontorybe/member/controller/RegistrationController.java index 3d054b2..7fa1c17 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/RegistrationController.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/RegistrationController.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.Builder; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -58,7 +59,7 @@ public ResponseEntity checkDuplicate( @PostMapping(consumes = MULTIPART_FORM_DATA_VALUE) public ResponseEntity register( @Login UserPrincipal user, - @RequestPart InitMemberInfoRequest req, + @RequestPart @Valid InitMemberInfoRequest req, @SingleFileUpload @RequestPart("file") List files ) { Long requestMemberId = user.getId(); diff --git a/src/main/java/org/fontory/fontorybe/member/controller/dto/InitMemberInfoRequest.java b/src/main/java/org/fontory/fontorybe/member/controller/dto/InitMemberInfoRequest.java index 3bb9513..ff9e248 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/dto/InitMemberInfoRequest.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/dto/InitMemberInfoRequest.java @@ -1,5 +1,9 @@ package org.fontory.fontorybe.member.controller.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Past; +import jakarta.validation.constraints.Size; import java.time.LocalDate; import lombok.AllArgsConstructor; @@ -13,8 +17,17 @@ @ToString @AllArgsConstructor public class InitMemberInfoRequest { + @NotBlank(message = "닉네임은 필수 입력 값입니다.") + @Size(min = 2, max = 20, message = "닉네임은 2자 이상 20자 이하로 입력해주세요.") private String nickname; + + @NotNull(message = "성별을 선택해주세요.") private Gender gender; + + @NotNull(message = "생년월일을 입력해주세요.") + @Past(message = "생년월일은 과거 날짜만 가능합니다.") private LocalDate birth; + + @NotNull(message = "이용약관 동의 여부를 선택해주세요.") private Boolean terms; } diff --git a/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberUpdateRequest.java b/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberUpdateRequest.java index 63179cd..b658a46 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberUpdateRequest.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberUpdateRequest.java @@ -1,5 +1,8 @@ package org.fontory.fontorybe.member.controller.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -10,6 +13,10 @@ @ToString @AllArgsConstructor public class MemberUpdateRequest { + @NotBlank(message = "닉네임은 필수 입력 값입니다.") + @Size(min = 2, max = 20, message = "닉네임은 2자 이상 20자 이하로 입력해주세요.") private String nickname; + + @NotNull(message = "이용약관 동의 여부를 선택해주세요.") private Boolean terms; } From 42c464eac32f02bc0f19bf44cab93a653dc1dc0d Mon Sep 17 00:00:00 2001 From: JuHyuk Lim Date: Fri, 16 May 2025 14:12:59 +0900 Subject: [PATCH 03/14] =?UTF-8?q?feat:=20=ED=8F=B0=ED=8A=B8=20=EC=98=81?= =?UTF-8?q?=EC=96=B4=20=EC=9D=B4=EB=A6=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../font/controller/dto/FontCreateDTO.java | 4 ++ .../font/controller/dto/FontUpdateDTO.java | 4 -- .../fontory/fontorybe/font/domain/Font.java | 49 +++++++------------ .../infrastructure/entity/FontEntity.java | 4 ++ .../font/service/FontServiceImpl.java | 15 ++++-- 5 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java index 2cc153d..5558a44 100644 --- a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java +++ b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java @@ -16,6 +16,10 @@ public class FontCreateDTO { @Size(min = 2, max = 30, message = "폰트 이름은 2자 이상 30자 이하로 입력해주세요.") private String name; + @NotBlank(message = "폰트 영어 이름은 필수 입력 값입니다.") + @Size(min = 2, max = 30, message = "폰트 이름은 2자 이상 30자 이하로 입력해주세요.") + private String engName; + @NotBlank(message = "폰트 예시는 필수 입력 값입니다.") @Size(min = 10, max = 255, message = "폰트 예시는 10자 이상 255자 이하로 입력해주세요.") private String example; diff --git a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontUpdateDTO.java b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontUpdateDTO.java index 81a373e..cf04ee9 100644 --- a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontUpdateDTO.java +++ b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontUpdateDTO.java @@ -8,10 +8,6 @@ @Getter @Builder public class FontUpdateDTO { - @NotBlank(message = "폰트 이름은 필수 입력 값입니다.") - @Size(min = 2, max = 30, message = "폰트 이름은 2자 이상 30자 이하로 입력해주세요.") - private String name; - @NotBlank(message = "폰트 예시는 필수 입력 값입니다.") @Size(min = 10, max = 255, message = "폰트 예시는 10자 이상 255자 이하로 입력해주세요.") private String example; diff --git a/src/main/java/org/fontory/fontorybe/font/domain/Font.java b/src/main/java/org/fontory/fontorybe/font/domain/Font.java index 3626303..8bf2a3f 100644 --- a/src/main/java/org/fontory/fontorybe/font/domain/Font.java +++ b/src/main/java/org/fontory/fontorybe/font/domain/Font.java @@ -22,6 +22,8 @@ public class Font { private String name; + private String engName; + private FontStatus status; private String example; @@ -53,6 +55,7 @@ public void increaseDownloadCount() { public static Font from(FontCreateDTO fontCreateDTO, Long memberId, String key) { return Font.builder() .name(fontCreateDTO.getName()) + .engName(fontCreateDTO.getEngName()) .status(FontStatus.PROGRESS) .example(fontCreateDTO.getExample()) .key(key) @@ -64,7 +67,8 @@ public static Font from(FontCreateDTO fontCreateDTO, Long memberId, String key) public Font update(FontUpdateDTO fontUpdateDTO) { return Font.builder() - .name(fontUpdateDTO.getName()) + .name(this.name) + .engName(this.engName) .example(fontUpdateDTO.getExample()) .id(this.id) .status(this.status) @@ -77,34 +81,19 @@ public Font update(FontUpdateDTO fontUpdateDTO) { .build(); } - public Font updateProgress(FontProgressUpdateDTO fontProgressUpdateDTO, Long fontId) { - - if (fontProgressUpdateDTO.getStatus() == FontStatus.DONE) { - return Font.builder() - .name(this.name) - .example(this.example) - .id(this.id) - .status(fontProgressUpdateDTO.getStatus()) - .downloadCount(this.downloadCount) - .bookmarkCount(this.bookmarkCount) - .key(this.key) - .memberId(this.memberId) - .createdAt(this.createdAt) - .updatedAt(this.updatedAt) - .build(); - } else { - return Font.builder() - .name(this.name) - .example(this.example) - .id(this.id) - .status(fontProgressUpdateDTO.getStatus()) - .downloadCount(this.downloadCount) - .bookmarkCount(this.bookmarkCount) - .key(this.key) - .memberId(this.memberId) - .createdAt(this.createdAt) - .updatedAt(this.updatedAt) - .build(); - } + public Font updateProgress(FontProgressUpdateDTO fontProgressUpdateDTO) { + return Font.builder() + .name(this.name) + .engName(this.engName) + .example(this.example) + .id(this.id) + .status(fontProgressUpdateDTO.getStatus()) + .downloadCount(this.downloadCount) + .bookmarkCount(this.bookmarkCount) + .key(this.key) + .memberId(this.memberId) + .createdAt(this.createdAt) + .updatedAt(this.updatedAt) + .build(); } } diff --git a/src/main/java/org/fontory/fontorybe/font/infrastructure/entity/FontEntity.java b/src/main/java/org/fontory/fontorybe/font/infrastructure/entity/FontEntity.java index 4707eed..f6eaf03 100644 --- a/src/main/java/org/fontory/fontorybe/font/infrastructure/entity/FontEntity.java +++ b/src/main/java/org/fontory/fontorybe/font/infrastructure/entity/FontEntity.java @@ -31,6 +31,8 @@ public class FontEntity extends BaseEntity { private String name; + private String engName; + @Enumerated(EnumType.STRING) private FontStatus status; @@ -49,6 +51,7 @@ public Font toModel() { return Font.builder() .id(id) .name(name) + .engName(engName) .status(status) .example(example) .downloadCount(downloadCount) @@ -64,6 +67,7 @@ public static FontEntity from(Font font) { return FontEntity.builder() .id(font.getId()) .name(font.getName()) + .engName(font.getEngName()) .status(font.getStatus()) .example(font.getExample()) .downloadCount(font.getDownloadCount()) diff --git a/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java b/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java index 958aa85..060a058 100644 --- a/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java +++ b/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java @@ -105,8 +105,8 @@ public FontUpdateResponse update(Long memberId, Long fontId, FontUpdateDTO fontU Font targetFont = getOrThrowById(fontId); checkFontOwnership(member.getId(), targetFont.getMemberId()); - checkContainsBadWord(fontUpdateDTO.getName(), fontUpdateDTO.getExample()); - + checkContainsBadWord(fontUpdateDTO.getExample()); + Font updatedFont = fontRepository.save(targetFont.update(fontUpdateDTO)); String woff2Url = cloudStorageService.getWoff2Url(updatedFont.getKey()); @@ -316,7 +316,7 @@ public FontUpdateResponse updateProgress(Long fontId, FontProgressUpdateDTO font log.info("Service executing: Updating font ID: {}", fontId); Font targetFont = getOrThrowById(fontId); - Font updatedFont = fontRepository.save(targetFont.updateProgress(fontProgressUpdateDTO, fontId)); + Font updatedFont = fontRepository.save(targetFont.updateProgress(fontProgressUpdateDTO)); String woff2Url = cloudStorageService.getWoff2Url(updatedFont.getKey()); if (fontProgressUpdateDTO.getStatus() == FontStatus.DONE) { @@ -383,4 +383,13 @@ private void checkContainsBadWord(String name, String example) { throw new FontContainsBadWordException(); } } + + private void checkContainsBadWord(String example) { + log.debug("Service detail: Checking bad word: example={}", example); + + if (badWordFiltering.blankCheck(example)) { + log.warn("Service warning: Font contains bad word: example={}", example); + throw new FontContainsBadWordException(); + } + } } From 9ef074d6f6f6429dde2bc10bc0d5fab35f7cb880 Mon Sep 17 00:00:00 2001 From: JuHyuk Lim Date: Fri, 16 May 2025 14:18:45 +0900 Subject: [PATCH 04/14] =?UTF-8?q?feat:=20=ED=8F=B0=ED=8A=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EA=B8=B0=EB=8A=A5=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../font/controller/FontController.java | 22 --------- .../font/controller/dto/FontUpdateDTO.java | 14 ------ .../font/controller/port/FontService.java | 1 - .../fontory/fontorybe/font/domain/Font.java | 18 ------- .../font/service/FontServiceImpl.java | 18 ------- .../font/FontControllerIntegrationTest.java | 47 ------------------- .../font/FontServiceIntegrationTest.java | 41 ---------------- 7 files changed, 161 deletions(-) delete mode 100644 src/main/java/org/fontory/fontorybe/font/controller/dto/FontUpdateDTO.java diff --git a/src/main/java/org/fontory/fontorybe/font/controller/FontController.java b/src/main/java/org/fontory/fontorybe/font/controller/FontController.java index 7a09e43..7f29903 100644 --- a/src/main/java/org/fontory/fontorybe/font/controller/FontController.java +++ b/src/main/java/org/fontory/fontorybe/font/controller/FontController.java @@ -25,7 +25,6 @@ import org.fontory.fontorybe.font.controller.dto.FontProgressResponse; import org.fontory.fontorybe.font.controller.dto.FontProgressUpdateDTO; import org.fontory.fontorybe.font.controller.dto.FontResponse; -import org.fontory.fontorybe.font.controller.dto.FontUpdateDTO; import org.fontory.fontorybe.font.controller.dto.FontUpdateResponse; import org.fontory.fontorybe.font.controller.port.FontService; import org.fontory.fontorybe.font.domain.Font; @@ -119,27 +118,6 @@ public ResponseEntity getFontProgress(@Login UserPrincipal userPrincipal) { .body(fontsProgress); } - @Operation(summary = "폰트 정보 수정") - @Parameter(name = "fontId", description = "수정할 폰트 ID") - @PutMapping("/{fontId}") - public ResponseEntity updateFont( - @RequestBody @Valid FontUpdateDTO fontUpdateDTO, - @PathVariable Long fontId, - @Login UserPrincipal userPrincipal - ) { - Long memberId = userPrincipal.getId(); - log.info("Request received: Update font ID: {} by member ID: {}, request: {}", - fontId, memberId, toJson(fontUpdateDTO)); - - FontUpdateResponse fontUpdateResponse = fontService.update(memberId, fontId, fontUpdateDTO); - log.info("Response sent: Font ID: {} updated successfully, name: {}", - fontUpdateResponse.getId(), fontUpdateResponse.getName()); - - return ResponseEntity - .status(HttpStatus.OK) - .body(fontUpdateResponse); - } - @Operation(summary = "내가 제작한 폰트") @GetMapping("/members") public ResponseEntity getFonts( diff --git a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontUpdateDTO.java b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontUpdateDTO.java deleted file mode 100644 index cf04ee9..0000000 --- a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontUpdateDTO.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.fontory.fontorybe.font.controller.dto; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; -import lombok.Builder; -import lombok.Getter; - -@Getter -@Builder -public class FontUpdateDTO { - @NotBlank(message = "폰트 예시는 필수 입력 값입니다.") - @Size(min = 10, max = 255, message = "폰트 예시는 10자 이상 255자 이하로 입력해주세요.") - private String example; -} diff --git a/src/main/java/org/fontory/fontorybe/font/controller/port/FontService.java b/src/main/java/org/fontory/fontorybe/font/controller/port/FontService.java index 63e2dc8..eaa4e6f 100644 --- a/src/main/java/org/fontory/fontorybe/font/controller/port/FontService.java +++ b/src/main/java/org/fontory/fontorybe/font/controller/port/FontService.java @@ -9,7 +9,6 @@ public interface FontService { Font create(Long memberId, FontCreateDTO fontCreateDTO, FileUploadResult fileDetails); List getFontProgress(Long memberId); - FontUpdateResponse update(Long memberId, Long fontId, FontUpdateDTO fontUpdateDTO); Font getOrThrowById(Long id); Page getFonts(Long memberId, int page, int size); FontResponse getFont(Long fondId, Long memberId); diff --git a/src/main/java/org/fontory/fontorybe/font/domain/Font.java b/src/main/java/org/fontory/fontorybe/font/domain/Font.java index 8bf2a3f..5120156 100644 --- a/src/main/java/org/fontory/fontorybe/font/domain/Font.java +++ b/src/main/java/org/fontory/fontorybe/font/domain/Font.java @@ -6,10 +6,8 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import org.fontory.fontorybe.file.domain.FileUploadResult; import org.fontory.fontorybe.font.controller.dto.FontCreateDTO; import org.fontory.fontorybe.font.controller.dto.FontProgressUpdateDTO; -import org.fontory.fontorybe.font.controller.dto.FontUpdateDTO; import org.fontory.fontorybe.font.infrastructure.entity.FontStatus; @Getter @@ -65,22 +63,6 @@ public static Font from(FontCreateDTO fontCreateDTO, Long memberId, String key) .build(); } - public Font update(FontUpdateDTO fontUpdateDTO) { - return Font.builder() - .name(this.name) - .engName(this.engName) - .example(fontUpdateDTO.getExample()) - .id(this.id) - .status(this.status) - .downloadCount(this.downloadCount) - .bookmarkCount(this.bookmarkCount) - .key(this.key) - .memberId(this.memberId) - .createdAt(this.createdAt) - .updatedAt(this.updatedAt) - .build(); - } - public Font updateProgress(FontProgressUpdateDTO fontProgressUpdateDTO) { return Font.builder() .name(this.name) diff --git a/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java b/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java index 060a058..94cc746 100644 --- a/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java +++ b/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java @@ -17,7 +17,6 @@ import org.fontory.fontorybe.font.controller.dto.FontProgressResponse; import org.fontory.fontorybe.font.controller.dto.FontProgressUpdateDTO; import org.fontory.fontorybe.font.controller.dto.FontResponse; -import org.fontory.fontorybe.font.controller.dto.FontUpdateDTO; import org.fontory.fontorybe.font.controller.dto.FontUpdateResponse; import org.fontory.fontorybe.font.controller.port.FontService; import org.fontory.fontorybe.font.domain.Font; @@ -97,23 +96,6 @@ public List getFontProgress(Long memberId) { return result; } - @Override - @Transactional - public FontUpdateResponse update(Long memberId, Long fontId, FontUpdateDTO fontUpdateDTO) { - log.info("Service executing: Updating font ID: {} for member ID: {}", fontId, memberId); - Member member = memberLookupService.getOrThrowById(memberId); - Font targetFont = getOrThrowById(fontId); - - checkFontOwnership(member.getId(), targetFont.getMemberId()); - checkContainsBadWord(fontUpdateDTO.getExample()); - - Font updatedFont = fontRepository.save(targetFont.update(fontUpdateDTO)); - String woff2Url = cloudStorageService.getWoff2Url(updatedFont.getKey()); - - log.info("Service completed: Font ID: {} updated successfully", fontId); - return FontUpdateResponse.from(updatedFont, woff2Url); - } - @Override @Transactional(readOnly = true) public Font getOrThrowById(Long id) { diff --git a/src/test/java/org/fontory/fontorybe/integration/font/FontControllerIntegrationTest.java b/src/test/java/org/fontory/fontorybe/integration/font/FontControllerIntegrationTest.java index 2eb3a9f..0aad20c 100644 --- a/src/test/java/org/fontory/fontorybe/integration/font/FontControllerIntegrationTest.java +++ b/src/test/java/org/fontory/fontorybe/integration/font/FontControllerIntegrationTest.java @@ -18,7 +18,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.nio.charset.StandardCharsets; -import java.util.UUID; import jakarta.servlet.http.Cookie; import org.fontory.fontorybe.authentication.application.port.JwtTokenProvider; @@ -30,7 +29,6 @@ import org.fontory.fontorybe.file.domain.FileUploadResult; import org.fontory.fontorybe.font.controller.dto.FontCreateDTO; import org.fontory.fontorybe.font.controller.dto.FontProgressUpdateDTO; -import org.fontory.fontorybe.font.controller.dto.FontUpdateDTO; import org.fontory.fontorybe.font.infrastructure.entity.FontStatus; import org.fontory.fontorybe.font.service.port.FontRequestProducer; import org.junit.jupiter.api.BeforeEach; @@ -203,51 +201,6 @@ void getFontProgressWithoutAuthHeader() throws Exception { .andExpect(jsonPath("$.errorMessage").value("Authentication Required.")); } - @Test - @DisplayName("PUT /fonts/{fontId} - update font success with valid Authorization header") - void updateFontSuccess() throws Exception { - // given - FontUpdateDTO updateDTO = FontUpdateDTO.builder() - .name(updateFontName) - .example(updateFontExample) - .build(); - - String jsonRequest = objectMapper.writeValueAsString(updateDTO); - - // when & then - mockMvc.perform(put("/fonts/{fontId}", existFontId) - .cookie(new Cookie("accessToken", validAccessToken)) - .contentType(MediaType.APPLICATION_JSON) - .content(jsonRequest)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.id", is(existFontId.intValue()))) - .andExpect(jsonPath("$.name", is(updateFontName))) - .andExpect(jsonPath("$.status").isNotEmpty()) - .andExpect(jsonPath("$.example", is(updateFontExample))) - .andExpect(jsonPath("$.memberId").isNotEmpty()) - .andExpect(jsonPath("$.createdAt").isNotEmpty()); - } - - @Test - @DisplayName("PUT /fonts/{fontId} - update font without Authorization header returns 401") - void updateFontWithoutAuthHeader() throws Exception { - // given - FontUpdateDTO updateDTO = FontUpdateDTO.builder() - .name(updateFontName) - .example(updateFontExample) - .build(); - - String jsonRequest = objectMapper.writeValueAsString(updateDTO); - - // when & then - mockMvc.perform(put("/fonts/{fontId}", existFontId) - .contentType(MediaType.APPLICATION_JSON) - .content(jsonRequest)) - .andExpect(status().isUnauthorized()) - .andExpect(content().contentType("application/json;charset=UTF-8")) - .andExpect(jsonPath("$.errorMessage").value("Authentication Required.")); - } - @Test @DisplayName("GET /fonts/members - success with valid Authorization header") void getMyFontsSuccess() throws Exception { diff --git a/src/test/java/org/fontory/fontorybe/integration/font/FontServiceIntegrationTest.java b/src/test/java/org/fontory/fontorybe/integration/font/FontServiceIntegrationTest.java index 6844014..00166a3 100644 --- a/src/test/java/org/fontory/fontorybe/integration/font/FontServiceIntegrationTest.java +++ b/src/test/java/org/fontory/fontorybe/integration/font/FontServiceIntegrationTest.java @@ -138,47 +138,6 @@ void getFontProgressSuccess() { result.forEach(font -> assertThat(font.getStatus()).isEqualTo(FontStatus.PROGRESS)); } - @Test - @DisplayName("font - update success test") - void updateFontSuccess() { - // given - FontUpdateDTO dto = FontUpdateDTO.builder() - .name("수정폰트") - .example("수정 폰트 예시입니다.") - .build(); - - // when - FontUpdateResponse updated = fontService.update(existMemberId, existFontId, dto); - - // then - assertAll( - () -> assertThat(updated.getId()).isEqualTo(existFontId), - () -> assertThat(updated.getName()).isEqualTo("수정폰트"), - () -> assertThat(updated.getExample()).isEqualTo("수정 폰트 예시입니다.") - ); - } - - @Test - @DisplayName("font - update fail test caused by access denied") - void updateFontAccessDeniedFail() { - // given - FontCreateDTO createDTO = FontCreateDTO.builder() - .name("다른사람폰트") - .example("다른예제") - .build(); - - Font elseFont = fontService.create(createdMemberId, createDTO, fileDetails); - - FontUpdateDTO updateDTO = FontUpdateDTO.builder() - .name("수정시도") - .example("예제수정") - .build(); - - // when & then - assertThatThrownBy(() -> fontService.update(existMemberId, elseFont.getId(), updateDTO)) - .isExactlyInstanceOf(FontOwnerMismatchException.class); - } - @Test @DisplayName("font - getOrThrowById success test") void getOrThrowByIdSuccess() { From ab558e518fc75816bcc34e042292d6c9d1ab40c3 Mon Sep 17 00:00:00 2001 From: JuHyuk Lim Date: Fri, 16 May 2025 17:06:23 +0900 Subject: [PATCH 05/14] =?UTF-8?q?feat:=20=ED=8F=B0=ED=8A=B8=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=A0=95=EA=B7=9C=20=ED=91=9C=ED=98=84=EC=8B=9D=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fontory/fontorybe/font/controller/dto/FontCreateDTO.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java index 5558a44..9d03b09 100644 --- a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java +++ b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java @@ -14,10 +14,12 @@ public class FontCreateDTO { @NotBlank(message = "폰트 이름은 필수 입력 값입니다.") @Size(min = 2, max = 30, message = "폰트 이름은 2자 이상 30자 이하로 입력해주세요.") + @Pattern(regexp = "^[가-힣]{2,30}$", message = "한글만 입력할 수 있습니다. (예: 가나다체)") private String name; @NotBlank(message = "폰트 영어 이름은 필수 입력 값입니다.") @Size(min = 2, max = 30, message = "폰트 이름은 2자 이상 30자 이하로 입력해주세요.") + @Pattern(regexp = "^[a-zA-Z]{2,30}$", message = "폰트 영어 이름은 영문 대소문자만 입력할 수 있습니다. (예: ABCD)") private String engName; @NotBlank(message = "폰트 예시는 필수 입력 값입니다.") From 4e74a78412a33d49fed7ff79d955734b8fa7731b Mon Sep 17 00:00:00 2001 From: JuHyuk Lim Date: Fri, 16 May 2025 17:08:10 +0900 Subject: [PATCH 06/14] feat: Validation Exception Handler --- .../adapter/inbound/GlobalExceptionHandler.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/org/fontory/fontorybe/common/adapter/inbound/GlobalExceptionHandler.java b/src/main/java/org/fontory/fontorybe/common/adapter/inbound/GlobalExceptionHandler.java index f014499..70fa9c0 100644 --- a/src/main/java/org/fontory/fontorybe/common/adapter/inbound/GlobalExceptionHandler.java +++ b/src/main/java/org/fontory/fontorybe/common/adapter/inbound/GlobalExceptionHandler.java @@ -3,6 +3,7 @@ import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.JwtException; import io.jsonwebtoken.MalformedJwtException; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.fontory.fontorybe.authentication.domain.exception.InvalidRefreshTokenException; import org.fontory.fontorybe.authentication.domain.exception.TokenNotFoundException; @@ -28,7 +29,9 @@ import org.fontory.fontorybe.member.domain.exception.MemberNotFoundException; import org.fontory.fontorybe.member.domain.exception.MemberOwnerMismatchException; import org.fontory.fontorybe.provide.domain.exception.ProvideNotFoundException; +import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.http.HttpStatus; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; @@ -38,6 +41,16 @@ @RequiredArgsConstructor public class GlobalExceptionHandler { + @ExceptionHandler(MethodArgumentNotValidException.class) + public BaseErrorResponse validationException(MethodArgumentNotValidException e) { + String message = e.getBindingResult() + .getFieldErrors() + .stream() + .map(DefaultMessageSourceResolvable::getDefaultMessage) + .collect(Collectors.joining(", ")); + return new BaseErrorResponse(message); + } + @ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler({MemberNotFoundException.class, FontNotFoundException.class, BookmarkNotFoundException.class}) public BaseErrorResponse notFoundException(Exception e) { From 9b7f610e02ecb7b81ebb131a55c744beab3e1ce3 Mon Sep 17 00:00:00 2001 From: JuHyuk Lim Date: Fri, 16 May 2025 17:08:18 +0900 Subject: [PATCH 07/14] chore: Spring Validation --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 4d1c7b6..9af4de8 100644 --- a/build.gradle +++ b/build.gradle @@ -31,6 +31,7 @@ dependencies { // Spring Boot Starters: implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-validation' // OAuth2 implementation 'org.springframework.session:spring-session-data-redis' From 823d8b28c670584ed960ca7a1825a23df3accfc0 Mon Sep 17 00:00:00 2001 From: JuHyuk Lim Date: Fri, 16 May 2025 17:11:11 +0900 Subject: [PATCH 08/14] =?UTF-8?q?feat:=20=ED=8F=B0=ED=8A=B8=20=EC=98=81?= =?UTF-8?q?=EC=96=B4=20=EC=9D=B4=EB=A6=84=EB=8F=84=20=EB=B9=84=EC=86=8D?= =?UTF-8?q?=EC=96=B4=20=EA=B2=80=EC=A6=9D=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../font/service/FontServiceImpl.java | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java b/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java index 94cc746..1527097 100644 --- a/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java +++ b/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java @@ -64,7 +64,7 @@ public Font create(Long memberId, FontCreateDTO fontCreateDTO, FileUploadResult throw new FontDuplicateNameExistsException(); } - checkContainsBadWord(fontCreateDTO.getName(), fontCreateDTO.getExample()); + checkFontNameAndExampleContainsBadWord(fontCreateDTO.getName(), fontCreateDTO.getEngName(), fontCreateDTO.getExample()); FileMetadata fileMetadata = fileService.getOrThrowById(fileDetails.getId()); @@ -357,20 +357,11 @@ private void checkFontStatusIsDone(Font targetFont) { } } - private void checkContainsBadWord(String name, String example) { - log.debug("Service detail: Checking bad word: name={}, example={}", name, example); + private void checkFontNameAndExampleContainsBadWord(String name, String engName, String example) { + log.debug("Service detail: Checking bad word: name={}, engName={} example={}", name, engName, example); - if (badWordFiltering.blankCheck(name) || badWordFiltering.blankCheck(example)) { - log.warn("Service warning: Font contains bad word: name={}, example={}", name, example); - throw new FontContainsBadWordException(); - } - } - - private void checkContainsBadWord(String example) { - log.debug("Service detail: Checking bad word: example={}", example); - - if (badWordFiltering.blankCheck(example)) { - log.warn("Service warning: Font contains bad word: example={}", example); + if (badWordFiltering.blankCheck(name) || badWordFiltering.blankCheck(engName) || badWordFiltering.blankCheck(example)) { + log.warn("Service warning: Font contains bad word: name={}, engName={}, example={}", name, engName, example); throw new FontContainsBadWordException(); } } From 541f97099537b30d05776c2802fa5af7df7c5090 Mon Sep 17 00:00:00 2001 From: JuHyuk Lim Date: Fri, 16 May 2025 17:20:10 +0900 Subject: [PATCH 09/14] =?UTF-8?q?refactor:=20=ED=8F=B0=ED=8A=B8=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=A0=95=EA=B7=9C=ED=91=9C=ED=98=84?= =?UTF-8?q?=EC=8B=9D=EC=97=90=20=EC=88=AB=EC=9E=90=20=ED=97=88=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fontory/fontorybe/font/controller/dto/FontCreateDTO.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java index 9d03b09..a5cbc75 100644 --- a/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java +++ b/src/main/java/org/fontory/fontorybe/font/controller/dto/FontCreateDTO.java @@ -14,12 +14,12 @@ public class FontCreateDTO { @NotBlank(message = "폰트 이름은 필수 입력 값입니다.") @Size(min = 2, max = 30, message = "폰트 이름은 2자 이상 30자 이하로 입력해주세요.") - @Pattern(regexp = "^[가-힣]{2,30}$", message = "한글만 입력할 수 있습니다. (예: 가나다체)") + @Pattern(regexp = "^[가-힣0-9]{2,30}$", message = "한글과 숫자만 입력할 수 있습니다. (예: 가나다체123)") private String name; @NotBlank(message = "폰트 영어 이름은 필수 입력 값입니다.") @Size(min = 2, max = 30, message = "폰트 이름은 2자 이상 30자 이하로 입력해주세요.") - @Pattern(regexp = "^[a-zA-Z]{2,30}$", message = "폰트 영어 이름은 영문 대소문자만 입력할 수 있습니다. (예: ABCD)") + @Pattern(regexp = "^[a-zA-Z0-9]{2,30}$", message = "영문 대소문자와 숫자만 입력할 수 있습니다. (예: ABCD123)") private String engName; @NotBlank(message = "폰트 예시는 필수 입력 값입니다.") From 560fff1caeef660ec7416a3201afc070dd714d76 Mon Sep 17 00:00:00 2001 From: JuHyuk Lim Date: Fri, 16 May 2025 17:20:23 +0900 Subject: [PATCH 10/14] =?UTF-8?q?test:=20=EC=98=81=EC=96=B4=20=ED=8F=B0?= =?UTF-8?q?=ED=8A=B8=20=EC=9D=B4=EB=A6=84=20=EC=B6=94=EA=B0=80=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../font/FontControllerIntegrationTest.java | 4 +++- .../font/FontServiceIntegrationTest.java | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/fontory/fontorybe/integration/font/FontControllerIntegrationTest.java b/src/test/java/org/fontory/fontorybe/integration/font/FontControllerIntegrationTest.java index 0aad20c..97861d6 100644 --- a/src/test/java/org/fontory/fontorybe/integration/font/FontControllerIntegrationTest.java +++ b/src/test/java/org/fontory/fontorybe/integration/font/FontControllerIntegrationTest.java @@ -81,7 +81,8 @@ class FontControllerIntegrationTest { private final String existFontKey = "key"; private final String existFontTemplateExtension = "jpg"; - private final String newFontName = "newFontName"; + private final String newFontName = "제작한글폰트1"; + private final String newFontEngName = "newFontEngName"; private final String newFontExample = "newFontExample"; private final String updateFontName = "updateFontName"; @@ -125,6 +126,7 @@ void addFontSuccess() throws Exception { // given FontCreateDTO createDTO = FontCreateDTO.builder() .name(newFontName) + .engName(newFontEngName) .example(newFontExample) .build(); diff --git a/src/test/java/org/fontory/fontorybe/integration/font/FontServiceIntegrationTest.java b/src/test/java/org/fontory/fontorybe/integration/font/FontServiceIntegrationTest.java index 00166a3..626ba03 100644 --- a/src/test/java/org/fontory/fontorybe/integration/font/FontServiceIntegrationTest.java +++ b/src/test/java/org/fontory/fontorybe/integration/font/FontServiceIntegrationTest.java @@ -93,6 +93,7 @@ void createFontSuccess() { // given FontCreateDTO dto = FontCreateDTO.builder() .name("생성폰트") + .engName("ENG1") .example("생성 폰트 예제입니다.") .build(); @@ -122,6 +123,7 @@ void getFontProgressSuccess() { existMemberId, FontCreateDTO.builder() .name("진행중폰트" + i) + .engName("ENG" + i) .example("예제" + i) .build(), fileDetails @@ -176,6 +178,7 @@ void getFontsSuccess() { existMemberId, FontCreateDTO.builder() .name("폰트" + i) + .engName("ENG" + i) .example("예제" + i) .build(), fileDetails @@ -239,6 +242,7 @@ void deleteFontAccessDeniedFail() { // given FontCreateDTO createDTO = FontCreateDTO.builder() .name("다른사람폰트") + .engName("ENG1") .example("다른예제") .build(); @@ -258,6 +262,7 @@ void getFontPageSuccess() { existMemberId, FontCreateDTO.builder() .name("페이지폰트1") + .engName("ENG1") .example("예제1") .build(), fileDetails @@ -267,6 +272,7 @@ void getFontPageSuccess() { existMemberId, FontCreateDTO.builder() .name("페이지폰트2") + .engName("ENG2") .example("예제2") .build(), fileDetails @@ -276,6 +282,7 @@ void getFontPageSuccess() { existMemberId, FontCreateDTO.builder() .name("페이지폰트") + .engName("ENG3") .example("예제3") .build(), fileDetails @@ -337,6 +344,7 @@ void getMyPopularFontsSuccess() { existMemberId, FontCreateDTO.builder() .name("폰트1") + .engName("ENG1") .example("예1") .build(), fileDetails @@ -346,6 +354,7 @@ void getMyPopularFontsSuccess() { existMemberId, FontCreateDTO.builder() .name("폰트2") + .engName("ENG2") .example("예2") .build(), fileDetails @@ -355,6 +364,7 @@ void getMyPopularFontsSuccess() { existMemberId, FontCreateDTO.builder() .name("폰트3") + .engName("ENG3") .example("예3") .build(), fileDetails @@ -399,6 +409,7 @@ void getPopularFontsSuccess() { existMemberId, FontCreateDTO.builder() .name("폰트1") + .engName("ENG1") .example("예1") .build(), fileDetails @@ -408,6 +419,7 @@ void getPopularFontsSuccess() { existMemberId, FontCreateDTO.builder() .name("폰트2") + .engName("ENG2") .example("예2") .build(), fileDetails @@ -417,6 +429,7 @@ void getPopularFontsSuccess() { existMemberId, FontCreateDTO.builder() .name("폰트3") + .engName("ENG3") .example("예3") .build(), fileDetails @@ -462,6 +475,7 @@ void updateFontProgressSuccess() { // given FontCreateDTO dto = FontCreateDTO.builder() .name("진행중폰트") + .engName("ENG1") .example("예제입니다") .build(); From e444c3729d29f43785ef91a9d7ca44ad8de61d51 Mon Sep 17 00:00:00 2001 From: JeongHoon Lee Date: Fri, 16 May 2025 18:28:27 +0900 Subject: [PATCH 11/14] fix bug empty files sent when onboarding & update memebr --- .../member/controller/ProfileController.java | 17 +++++++++----- .../controller/RegistrationController.java | 22 +++++++++++++------ .../controller/port/MemberOnboardService.java | 1 + .../fontorybe/member/domain/Member.java | 16 ++++++++++++++ .../service/MemberOnboardServiceImpl.java | 16 ++++++++++++++ src/main/resources/application.properties | 4 ++++ .../ProfileControllerIntegrationTest.java | 3 ++- .../fontorybe/unit/mock/TestContainer.java | 1 + 8 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java b/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java index b651cee..ed2fdae 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java @@ -72,21 +72,26 @@ public ResponseEntity getMyProfile( public ResponseEntity updateMember( @Login UserPrincipal userPrincipal, @RequestPart MemberUpdateRequest req, - @SingleFileUpload @RequestPart("file") List files + @SingleFileUpload @RequestPart(value = "file", required = false) List files ) { Long requestMemberId = userPrincipal.getId(); - MultipartFile file = extractSingleMultipartFile(files); - log.info("Request received: update member ID: {} with request: {}", requestMemberId, req); - logFileDetails(file, "Member profile image upload"); - FileUploadResult fileUploadResult = fileService.uploadProfileImage(file, requestMemberId); + if (files != null && !files.isEmpty()) { + MultipartFile file = extractSingleMultipartFile(files); + logFileDetails(file, "Member profile image upload"); + FileUploadResult fileUploadResult = fileService.uploadProfileImage(file, requestMemberId); + log.info("fileUploadResult: {}", fileUploadResult); + } else { + log.info("No profile image upload found"); + } + Member updatedMember = memberUpdateService.update(requestMemberId, req); log.info("Updated : Member ID: {} Updated successfully with nickname: {}, terms : {}", updatedMember.getId(), updatedMember.getNickname(), updatedMember.getTerms()); - MyProfileResponse myProfileResponse = MyProfileResponse.from(updatedMember, fileUploadResult.getFileUrl()); + MyProfileResponse myProfileResponse = MyProfileResponse.from(updatedMember, cloudStorageService.getProfileImageUrl(updatedMember.getProfileImageKey())); log.info("Response sent: MyProfileDto : {}", myProfileResponse); return ResponseEntity diff --git a/src/main/java/org/fontory/fontorybe/member/controller/RegistrationController.java b/src/main/java/org/fontory/fontorybe/member/controller/RegistrationController.java index 3d054b2..631c496 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/RegistrationController.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/RegistrationController.java @@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j; import org.fontory.fontorybe.authentication.adapter.inbound.annotation.Login; import org.fontory.fontorybe.authentication.domain.UserPrincipal; +import org.fontory.fontorybe.file.application.port.CloudStorageService; import org.fontory.fontorybe.file.application.port.FileService; import org.fontory.fontorybe.file.domain.FileUploadResult; import org.fontory.fontorybe.file.application.annotation.SingleFileUpload; @@ -17,6 +18,7 @@ import org.fontory.fontorybe.member.domain.Member; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.parameters.P; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -32,6 +34,7 @@ @RequestMapping("/register") @Tag(name = "사용자 - 신규", description = "회원가입/온보딩") public class RegistrationController { + private final CloudStorageService cloudStorageService; private final MemberLookupService memberLookupService; private final MemberOnboardService memberOnboardService; private final FileService fileService; @@ -59,24 +62,29 @@ public ResponseEntity checkDuplicate( public ResponseEntity register( @Login UserPrincipal user, @RequestPart InitMemberInfoRequest req, - @SingleFileUpload @RequestPart("file") List files + @SingleFileUpload @RequestPart(value = "file", required = false) List files ) { Long requestMemberId = user.getId(); - MultipartFile file = extractSingleMultipartFile(files); - log.info("Request received: Create member ID: {} with request: {}", requestMemberId, req); - logFileDetails(file, "Member profile image upload"); - FileUploadResult fileUploadResult = fileService.uploadProfileImage(file, requestMemberId); - Member updatedMember = memberOnboardService.initNewMemberInfo(requestMemberId, req, fileUploadResult); + Member updatedMember; + if (files != null && !files.isEmpty()) { + MultipartFile file = extractSingleMultipartFile(files); + logFileDetails(file, "Member profile image upload"); + FileUploadResult fileUploadResult = fileService.uploadProfileImage(file, requestMemberId); + updatedMember = memberOnboardService.initNewMemberInfo(requestMemberId, req, fileUploadResult); + } else { + log.info("No profile image upload found"); + updatedMember = memberOnboardService.initNewMemberInfo(requestMemberId, req); + } log.info("Response sent: Member ID: {} Created successfully with nickname: {}", updatedMember.getId(), updatedMember.getNickname()); return ResponseEntity .status(HttpStatus.CREATED) - .body(MemberCreateResponse.from(updatedMember, fileUploadResult.getFileUrl())); + .body(MemberCreateResponse.from(updatedMember, cloudStorageService.getProfileImageUrl(updatedMember.getProfileImageKey()))); } private void logFileDetails(MultipartFile file, String context) { diff --git a/src/main/java/org/fontory/fontorybe/member/controller/port/MemberOnboardService.java b/src/main/java/org/fontory/fontorybe/member/controller/port/MemberOnboardService.java index 8441560..65b55e8 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/port/MemberOnboardService.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/port/MemberOnboardService.java @@ -8,4 +8,5 @@ public interface MemberOnboardService { Member fetchOrCreateMember(Provide p); Member initNewMemberInfo(Long requestMemberId, InitMemberInfoRequest initMemberInfoRequest, FileUploadResult fileUploadResult); + Member initNewMemberInfo(Long requestMemberId, InitMemberInfoRequest initMemberInfoRequest); } diff --git a/src/main/java/org/fontory/fontorybe/member/domain/Member.java b/src/main/java/org/fontory/fontorybe/member/domain/Member.java index dd1d166..3e0d323 100644 --- a/src/main/java/org/fontory/fontorybe/member/domain/Member.java +++ b/src/main/java/org/fontory/fontorybe/member/domain/Member.java @@ -65,6 +65,22 @@ public Member initNewMemberInfo(InitMemberInfoRequest initNewMemberInfo, String .build(); } + public Member initNewMemberInfo(InitMemberInfoRequest initNewMemberInfo) { + return Member.builder() + .id(this.id) + .nickname(initNewMemberInfo.getNickname()) + .gender(initNewMemberInfo.getGender()) + .birth(initNewMemberInfo.getBirth()) + .terms(initNewMemberInfo.getTerms()) + .profileImageKey(this.profileImageKey) + .createdAt(this.createdAt) + .provideId(this.provideId) + .deletedAt(this.deletedAt) + .provideId(this.provideId) + .status(MemberStatus.ACTIVATE) + .build(); + } + public Member update(MemberUpdateRequest memberUpdateRequest) { return Member.builder() //tobe update diff --git a/src/main/java/org/fontory/fontorybe/member/service/MemberOnboardServiceImpl.java b/src/main/java/org/fontory/fontorybe/member/service/MemberOnboardServiceImpl.java index 07c615f..ec9fd37 100644 --- a/src/main/java/org/fontory/fontorybe/member/service/MemberOnboardServiceImpl.java +++ b/src/main/java/org/fontory/fontorybe/member/service/MemberOnboardServiceImpl.java @@ -58,6 +58,22 @@ public Member initNewMemberInfo(Long requestMemberId, return memberRepository.save(targetMember.initNewMemberInfo(initNewMemberInfoRequest, fileMetadata.getKey())); } + @Override + @Transactional + public Member initNewMemberInfo(Long requestMemberId, + InitMemberInfoRequest initNewMemberInfoRequest) { + Member targetMember = memberLookupService.getOrThrowById(requestMemberId); + if (targetMember.getStatus() == MemberStatus.ACTIVATE) { + throw new MemberAlreadyJoinedException(); + } else if (memberLookupService.existsByNickname(initNewMemberInfoRequest.getNickname())) { + throw new MemberDuplicateNameExistsException(); + } + + checkContainsBadWord(initNewMemberInfoRequest.getNickname()); + + return memberRepository.save(targetMember.initNewMemberInfo(initNewMemberInfoRequest)); + } + private void checkContainsBadWord(String nickname) { if (badWordFiltering.blankCheck(nickname)) { throw new MemberContainsBadWordException(); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1ad54b1..b6e7e95 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -34,3 +34,7 @@ member.default.birth=1999-12-31 member.default.profile-image-key=default member.default.terms-agree=false +# max file size +spring.servlet.multipart.maxFileSize=5MB +# max total file size +spring.servlet.multipart.maxRequestSize=10MB \ No newline at end of file diff --git a/src/test/java/org/fontory/fontorybe/integration/member/controller/ProfileControllerIntegrationTest.java b/src/test/java/org/fontory/fontorybe/integration/member/controller/ProfileControllerIntegrationTest.java index bb20fbc..895cb5f 100644 --- a/src/test/java/org/fontory/fontorybe/integration/member/controller/ProfileControllerIntegrationTest.java +++ b/src/test/java/org/fontory/fontorybe/integration/member/controller/ProfileControllerIntegrationTest.java @@ -27,6 +27,7 @@ import static org.fontory.fontorybe.TestConstants.*; import static org.fontory.fontorybe.TestConstants.UPDATE_MEMBER_TERMS; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; @@ -106,7 +107,7 @@ void updateMemberSuccessTest() throws Exception { .andExpect(jsonPath("$.memberId", is(TEST_MEMBER_ID.intValue()))) .andExpect(jsonPath("$.nickname", is(UPDATE_MEMBER_NICKNAME))) .andExpect(jsonPath("$.terms", is(UPDATE_MEMBER_TERMS))) - .andExpect(jsonPath("$.profileImageUrl", is(testMember.getProfileImageKey()))) + .andExpect(jsonPath("$.profileImageUrl", containsString(testMember.getProfileImageKey()))) .andExpect(jsonPath("$.gender", is(testMember.getGender().name()))) .andExpect(jsonPath("$.birth", is(testMember.getBirth().toString()))); } diff --git a/src/test/java/org/fontory/fontorybe/unit/mock/TestContainer.java b/src/test/java/org/fontory/fontorybe/unit/mock/TestContainer.java index 064f1a8..8e556b7 100644 --- a/src/test/java/org/fontory/fontorybe/unit/mock/TestContainer.java +++ b/src/test/java/org/fontory/fontorybe/unit/mock/TestContainer.java @@ -191,6 +191,7 @@ public TestContainer() { registrationController = RegistrationController.builder() .memberLookupService(memberLookupService) .memberOnboardService(memberOnboardService) + .cloudStorageService(cloudStorageService) .fileService(fileService) .build(); } From 11da0c63505e0b3b0f2ca4f31f509966845e5485 Mon Sep 17 00:00:00 2001 From: JeongHoon Lee Date: Sat, 17 May 2025 00:21:13 +0900 Subject: [PATCH 12/14] fix: /member/me with onboarding user return 401 Unauthorized --- .../exception/AuthenticationRequiredException.java | 10 ++++++++++ .../common/adapter/inbound/GlobalExceptionHandler.java | 7 +++++++ .../fontorybe/member/controller/ProfileController.java | 5 +++++ 3 files changed, 22 insertions(+) create mode 100644 src/main/java/org/fontory/fontorybe/authentication/domain/exception/AuthenticationRequiredException.java diff --git a/src/main/java/org/fontory/fontorybe/authentication/domain/exception/AuthenticationRequiredException.java b/src/main/java/org/fontory/fontorybe/authentication/domain/exception/AuthenticationRequiredException.java new file mode 100644 index 0000000..26a9f8f --- /dev/null +++ b/src/main/java/org/fontory/fontorybe/authentication/domain/exception/AuthenticationRequiredException.java @@ -0,0 +1,10 @@ +package org.fontory.fontorybe.authentication.domain.exception; + +import org.fontory.fontorybe.common.domain.SkipDiscordNotification; + +@SkipDiscordNotification +public class AuthenticationRequiredException extends RuntimeException { + public AuthenticationRequiredException() { + super("Authentication required"); + } +} diff --git a/src/main/java/org/fontory/fontorybe/common/adapter/inbound/GlobalExceptionHandler.java b/src/main/java/org/fontory/fontorybe/common/adapter/inbound/GlobalExceptionHandler.java index f014499..534c869 100644 --- a/src/main/java/org/fontory/fontorybe/common/adapter/inbound/GlobalExceptionHandler.java +++ b/src/main/java/org/fontory/fontorybe/common/adapter/inbound/GlobalExceptionHandler.java @@ -4,6 +4,7 @@ import io.jsonwebtoken.JwtException; import io.jsonwebtoken.MalformedJwtException; import lombok.RequiredArgsConstructor; +import org.fontory.fontorybe.authentication.domain.exception.AuthenticationRequiredException; import org.fontory.fontorybe.authentication.domain.exception.InvalidRefreshTokenException; import org.fontory.fontorybe.authentication.domain.exception.TokenNotFoundException; import org.fontory.fontorybe.bookmark.domain.exception.BookmarkAlreadyException; @@ -169,4 +170,10 @@ public BaseErrorResponse fileNotFoundException(FileNotFoundException e) { public BaseErrorResponse containsBadWordException(Exception e) { return new BaseErrorResponse(e.getMessage()); } + + @ResponseStatus(HttpStatus.UNAUTHORIZED) + @ExceptionHandler(AuthenticationRequiredException.class) + public BaseErrorResponse authenticationRequiredException(AuthenticationRequiredException e) { + return new BaseErrorResponse(e.getMessage()); + } } diff --git a/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java b/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java index 6281204..4c2c12d 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java @@ -10,6 +10,7 @@ import org.fontory.fontorybe.authentication.adapter.inbound.annotation.Login; import org.fontory.fontorybe.authentication.application.AuthService; import org.fontory.fontorybe.authentication.domain.UserPrincipal; +import org.fontory.fontorybe.authentication.domain.exception.AuthenticationRequiredException; import org.fontory.fontorybe.file.application.port.CloudStorageService; import org.fontory.fontorybe.file.application.port.FileService; import org.fontory.fontorybe.file.domain.FileUploadResult; @@ -20,6 +21,7 @@ import org.fontory.fontorybe.member.controller.port.MemberLookupService; import org.fontory.fontorybe.member.controller.port.MemberUpdateService; import org.fontory.fontorybe.member.domain.Member; +import org.fontory.fontorybe.member.infrastructure.entity.MemberStatus; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -54,6 +56,9 @@ public ResponseEntity getMyProfile( log.info("Request received: getMyInfo member ID: {}", requestMemberId); Member lookupMember = memberLookupService.getOrThrowById(requestMemberId); + if (lookupMember.getStatus().equals(MemberStatus.ONBOARDING)) { + throw new AuthenticationRequiredException(); + } String fileUrl = cloudStorageService.getProfileImageUrl(lookupMember.getProfileImageKey()); log.info("ProfileImageUrl generated : {}", fileUrl); From 26b86e40fb48ba8b2d4747e3895d570f1a2a8cb0 Mon Sep 17 00:00:00 2001 From: JuHyuk Lim Date: Mon, 19 May 2025 13:34:16 +0900 Subject: [PATCH 13/14] =?UTF-8?q?feat:=20=EB=A9=94=EC=84=B8=EC=A7=80=20?= =?UTF-8?q?=ED=81=90=EC=97=90=20=ED=8F=B0=ED=8A=B8=20=EC=98=81=EC=96=B4=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=A0=84=EB=8B=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fontorybe/font/service/dto/FontRequestProduceDto.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/fontory/fontorybe/font/service/dto/FontRequestProduceDto.java b/src/main/java/org/fontory/fontorybe/font/service/dto/FontRequestProduceDto.java index 555919d..255fa9f 100644 --- a/src/main/java/org/fontory/fontorybe/font/service/dto/FontRequestProduceDto.java +++ b/src/main/java/org/fontory/fontorybe/font/service/dto/FontRequestProduceDto.java @@ -15,6 +15,7 @@ public class FontRequestProduceDto { private Long fontId; private String fileKey; private String fontName; + private String fontEngName; private String templateURL; private String author; private String requestUUID; @@ -25,6 +26,7 @@ public static FontRequestProduceDto from(Font font, Member member, String templa .fileKey(font.getKey()) .fontId(font.getId()) .fontName(font.getName()) + .fontEngName(font.getEngName()) .templateURL(templateUrl) .author(member.getNickname()) .requestUUID(MDC.get("requestId")) From 522b69270a126d322d1e21cee8fe61f4de29d33a Mon Sep 17 00:00:00 2001 From: JeongHoon Lee Date: Mon, 19 May 2025 18:21:04 +0900 Subject: [PATCH 14/14] refactor: remove terms properties in member entity --- .../application/DevTokenInitializer.java | 1 - .../member/controller/ProfileController.java | 3 +- .../controller/dto/InitMemberInfoRequest.java | 3 -- .../controller/dto/MemberCreateResponse.java | 2 -- .../controller/dto/MemberUpdateRequest.java | 4 +-- .../controller/dto/MemberUpdateResponse.java | 2 -- .../controller/dto/MyProfileResponse.java | 6 ---- .../fontorybe/member/domain/Member.java | 11 ------- .../member/domain/MemberDefaults.java | 8 ----- .../infrastructure/entity/MemberEntity.java | 4 --- src/main/resources/application.properties | 1 - .../org/fontory/fontorybe/TestConstants.java | 3 -- .../ProfileControllerIntegrationTest.java | 6 ++-- ...RegistrationControllerIntegrationTest.java | 2 +- .../MemberUpdateServiceIntegrationTest.java | 23 ++++++------- .../unit/file/FileRequestMapperTest.java | 3 +- .../fontorybe/unit/file/FileServiceTest.java | 3 +- .../controller/ProfileControllerTest.java | 7 ++-- .../service/MemberUpdateServiceTest.java | 32 ++++++++----------- .../unit/mock/FakeMemberRepository.java | 2 -- .../fontorybe/unit/mock/TestContainer.java | 7 ++-- src/test/resources/sql/createFileTestData.sql | 4 +-- src/test/resources/sql/createFontTestData.sql | 8 ++--- .../resources/sql/createMemberTestData.sql | 4 +-- 24 files changed, 44 insertions(+), 105 deletions(-) diff --git a/src/main/java/org/fontory/fontorybe/common/application/DevTokenInitializer.java b/src/main/java/org/fontory/fontorybe/common/application/DevTokenInitializer.java index 132b4f6..4312f1a 100644 --- a/src/main/java/org/fontory/fontorybe/common/application/DevTokenInitializer.java +++ b/src/main/java/org/fontory/fontorybe/common/application/DevTokenInitializer.java @@ -95,7 +95,6 @@ public void initTokens() { Member m = Member.builder() .gender(Gender.MALE) .provideId(provide.getId()) - .terms(true) .birth(LocalDate.now()) .nickname("Tester") .profileImageKey(memberDefaults.getProfileImageKey()) diff --git a/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java b/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java index 4c2c12d..26f24ba 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/ProfileController.java @@ -94,8 +94,7 @@ public ResponseEntity updateMember( } Member updatedMember = memberUpdateService.update(requestMemberId, req); - log.info("Updated : Member ID: {} Updated successfully with nickname: {}, terms : {}", - updatedMember.getId(), updatedMember.getNickname(), updatedMember.getTerms()); + log.info("Updated : Member ID: {} Updated successfully with nickname: {}", updatedMember.getId(), updatedMember.getNickname()); MyProfileResponse myProfileResponse = MyProfileResponse.from(updatedMember, cloudStorageService.getProfileImageUrl(updatedMember.getProfileImageKey())); log.info("Response sent: MyProfileDto : {}", myProfileResponse); diff --git a/src/main/java/org/fontory/fontorybe/member/controller/dto/InitMemberInfoRequest.java b/src/main/java/org/fontory/fontorybe/member/controller/dto/InitMemberInfoRequest.java index ff9e248..9217ebb 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/dto/InitMemberInfoRequest.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/dto/InitMemberInfoRequest.java @@ -27,7 +27,4 @@ public class InitMemberInfoRequest { @NotNull(message = "생년월일을 입력해주세요.") @Past(message = "생년월일은 과거 날짜만 가능합니다.") private LocalDate birth; - - @NotNull(message = "이용약관 동의 여부를 선택해주세요.") - private Boolean terms; } diff --git a/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberCreateResponse.java b/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberCreateResponse.java index 510988c..ef241c9 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberCreateResponse.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberCreateResponse.java @@ -15,7 +15,6 @@ public class MemberCreateResponse { private final Gender gender; private final String profileImageUrl; private final LocalDate birth; - private final boolean terms; private final LocalDateTime createdAt; public static MemberCreateResponse from(Member member, String url) { @@ -24,7 +23,6 @@ public static MemberCreateResponse from(Member member, String url) { .gender(member.getGender()) .profileImageUrl(url) .birth(member.getBirth()) - .terms(member.getTerms()) .createdAt(member.getCreatedAt()) .build(); } diff --git a/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberUpdateRequest.java b/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberUpdateRequest.java index b658a46..3a9780a 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberUpdateRequest.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberUpdateRequest.java @@ -16,7 +16,5 @@ public class MemberUpdateRequest { @NotBlank(message = "닉네임은 필수 입력 값입니다.") @Size(min = 2, max = 20, message = "닉네임은 2자 이상 20자 이하로 입력해주세요.") private String nickname; - - @NotNull(message = "이용약관 동의 여부를 선택해주세요.") - private Boolean terms; } + diff --git a/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberUpdateResponse.java b/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberUpdateResponse.java index 676718f..157b57d 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberUpdateResponse.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/dto/MemberUpdateResponse.java @@ -11,14 +11,12 @@ public class MemberUpdateResponse { private String nickname; private String profileImage; - private Boolean terms; private LocalDateTime updatedAt; public static MemberUpdateResponse from(Member member) { return MemberUpdateResponse.builder() .nickname(member.getNickname()) .profileImage(member.getProfileImageKey()) - .terms(member.getTerms()) .updatedAt(member.getUpdatedAt()) .build(); } diff --git a/src/main/java/org/fontory/fontorybe/member/controller/dto/MyProfileResponse.java b/src/main/java/org/fontory/fontorybe/member/controller/dto/MyProfileResponse.java index f396acc..7c93aab 100644 --- a/src/main/java/org/fontory/fontorybe/member/controller/dto/MyProfileResponse.java +++ b/src/main/java/org/fontory/fontorybe/member/controller/dto/MyProfileResponse.java @@ -16,7 +16,6 @@ public class MyProfileResponse { private String nickname; private Gender gender; private LocalDate birth; - private boolean terms; private String profileImageUrl; public static MyProfileResponse from(Member member, String url) { @@ -25,12 +24,7 @@ public static MyProfileResponse from(Member member, String url) { .nickname(member.getNickname()) .birth(member.getBirth()) .gender(member.getGender()) - .terms(member.getTerms()) .profileImageUrl(url) .build(); } - - public boolean getTerms() { - return this.terms; - } } diff --git a/src/main/java/org/fontory/fontorybe/member/domain/Member.java b/src/main/java/org/fontory/fontorybe/member/domain/Member.java index 3e0d323..e84790e 100644 --- a/src/main/java/org/fontory/fontorybe/member/domain/Member.java +++ b/src/main/java/org/fontory/fontorybe/member/domain/Member.java @@ -23,8 +23,6 @@ public class Member { private LocalDate birth; - private boolean terms; - private String profileImageKey; private LocalDateTime createdAt; @@ -42,7 +40,6 @@ public static Member fromDefaults(MemberDefaults memberDefaults, String nickname .nickname(nickname) .gender(memberDefaults.getGender()) .birth(memberDefaults.getBirth()) - .terms(memberDefaults.getTerms()) .profileImageKey(memberDefaults.getProfileImageKey()) .provideId(provide.getId()) .status(MemberStatus.ONBOARDING) @@ -55,7 +52,6 @@ public Member initNewMemberInfo(InitMemberInfoRequest initNewMemberInfo, String .nickname(initNewMemberInfo.getNickname()) .gender(initNewMemberInfo.getGender()) .birth(initNewMemberInfo.getBirth()) - .terms(initNewMemberInfo.getTerms()) .profileImageKey(profileImageKey) .createdAt(this.createdAt) .provideId(this.provideId) @@ -71,7 +67,6 @@ public Member initNewMemberInfo(InitMemberInfoRequest initNewMemberInfo) { .nickname(initNewMemberInfo.getNickname()) .gender(initNewMemberInfo.getGender()) .birth(initNewMemberInfo.getBirth()) - .terms(initNewMemberInfo.getTerms()) .profileImageKey(this.profileImageKey) .createdAt(this.createdAt) .provideId(this.provideId) @@ -85,7 +80,6 @@ public Member update(MemberUpdateRequest memberUpdateRequest) { return Member.builder() //tobe update .nickname(memberUpdateRequest.getNickname()) - .terms(memberUpdateRequest.getTerms()) //not to be update .id(this.id) @@ -104,10 +98,6 @@ public void disable() { this.deletedAt = LocalDateTime.now(); } - public boolean getTerms() { - return this.terms; - } - public Member setProfileImageKey(String profileImageKey) { return Member.builder() .profileImageKey(profileImageKey) @@ -119,7 +109,6 @@ public Member setProfileImageKey(String profileImageKey) { .createdAt(this.createdAt) .provideId(this.provideId) .deletedAt(this.deletedAt) - .terms(this.terms) .provideId(this.provideId) .status(this.status) .build(); diff --git a/src/main/java/org/fontory/fontorybe/member/domain/MemberDefaults.java b/src/main/java/org/fontory/fontorybe/member/domain/MemberDefaults.java index b9ff27f..fef9010 100644 --- a/src/main/java/org/fontory/fontorybe/member/domain/MemberDefaults.java +++ b/src/main/java/org/fontory/fontorybe/member/domain/MemberDefaults.java @@ -13,22 +13,14 @@ @ConfigurationProperties(prefix="member.default") public class MemberDefaults { private LocalDate birth; - private boolean termsAgree; private String profileImageKey; private Gender gender; @ConstructorBinding public MemberDefaults(LocalDate birth, - boolean termsAgree, String profileImageKey) { this.birth = birth; - this.termsAgree = termsAgree; this.profileImageKey = profileImageKey; this.gender = Gender.NONE; } - - public boolean getTerms() { - return this.termsAgree; - } - } diff --git a/src/main/java/org/fontory/fontorybe/member/infrastructure/entity/MemberEntity.java b/src/main/java/org/fontory/fontorybe/member/infrastructure/entity/MemberEntity.java index 8fe3678..d62e7d5 100644 --- a/src/main/java/org/fontory/fontorybe/member/infrastructure/entity/MemberEntity.java +++ b/src/main/java/org/fontory/fontorybe/member/infrastructure/entity/MemberEntity.java @@ -36,8 +36,6 @@ public class MemberEntity extends BaseEntity { private LocalDate birth; - private Boolean terms; - private String profileImageKey; private Long provideId; @@ -53,7 +51,6 @@ public Member toModel() { .nickname(nickname) .gender(gender) .birth(birth) - .terms(terms) .profileImageKey(profileImageKey) .provideId(provideId) .status(status) @@ -69,7 +66,6 @@ public static MemberEntity from(Member member) { .nickname(member.getNickname()) .gender(member.getGender()) .birth(member.getBirth()) - .terms(member.getTerms()) .profileImageKey(member.getProfileImageKey()) .provideId(member.getProvideId()) .status(member.getStatus()) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index d51fff4..fcc6af4 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -32,7 +32,6 @@ jwt.refresh-token-validity-ms=604800000 member.default.birth=1999-12-31 member.default.profile-image-key=default -member.default.terms-agree=false # max file size spring.servlet.multipart.maxFileSize=5MB diff --git a/src/test/java/org/fontory/fontorybe/TestConstants.java b/src/test/java/org/fontory/fontorybe/TestConstants.java index a96bde7..4a1d60b 100644 --- a/src/test/java/org/fontory/fontorybe/TestConstants.java +++ b/src/test/java/org/fontory/fontorybe/TestConstants.java @@ -11,7 +11,6 @@ private TestConstants() {} // 인스턴스 생성 방지 // NOT created in SQL public static final Gender NEW_MEMBER_GENDER = Gender.FEMALE; - public static final boolean NEW_MEMBER_TERMS = false; public static final LocalDate NEW_MEMBER_BIRTH = LocalDate.of(2025, 1, 22); public static final String NEW_MEMBER_NICKNAME = "newMemberNickName"; public static final String NEW_MEMBER_PROFILE_KEY = "newMemberProfileImage"; @@ -23,7 +22,6 @@ private TestConstants() {} // 인스턴스 생성 방지 public static final String DEFAULT_PROFILE_KEY = "defaultProfileImage"; // Created in SQL public static final Gender TEST_MEMBER_GENDER = Gender.MALE; - public static final boolean TEST_MEMBER_TERMS = true; public static final LocalDate TEST_MEMBER_BIRTH = LocalDate.of(2025, 1, 26); public static final String TEST_MEMBER_NICKNAME = "testMemberNickName"; public static final String TEST_MEMBER_PROFILE_KEY = "testMemberProfileImage"; @@ -36,7 +34,6 @@ private TestConstants() {} // 인스턴스 생성 방지 public static final Long TEST_PROVIDE_ID = 1L; public static final Long NON_EXIST_ID = -1L; - public static final boolean UPDATE_MEMBER_TERMS = Boolean.FALSE; public static final String UPDATE_MEMBER_NICKNAME = "updateMemberNickName"; public static final String UPDATE_MEMBER_PROFILE_KEY= "updateMemberProfileImage"; diff --git a/src/test/java/org/fontory/fontorybe/integration/member/controller/ProfileControllerIntegrationTest.java b/src/test/java/org/fontory/fontorybe/integration/member/controller/ProfileControllerIntegrationTest.java index 895cb5f..78b3945 100644 --- a/src/test/java/org/fontory/fontorybe/integration/member/controller/ProfileControllerIntegrationTest.java +++ b/src/test/java/org/fontory/fontorybe/integration/member/controller/ProfileControllerIntegrationTest.java @@ -26,7 +26,6 @@ import java.util.UUID; import static org.fontory.fontorybe.TestConstants.*; -import static org.fontory.fontorybe.TestConstants.UPDATE_MEMBER_TERMS; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.mockito.ArgumentMatchers.any; @@ -80,7 +79,7 @@ void checkDuplicateFalseTest() throws Exception { @Test @DisplayName("PUT /member - update member success with valid Authorization JWT Cookie") void updateMemberSuccessTest() throws Exception { - MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(UPDATE_MEMBER_NICKNAME, UPDATE_MEMBER_TERMS); + MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(UPDATE_MEMBER_NICKNAME); String jsonRequest = objectMapper.writeValueAsString(memberUpdateRequest); MockMultipartFile jsonPart = new MockMultipartFile( "req", @@ -106,7 +105,6 @@ void updateMemberSuccessTest() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.memberId", is(TEST_MEMBER_ID.intValue()))) .andExpect(jsonPath("$.nickname", is(UPDATE_MEMBER_NICKNAME))) - .andExpect(jsonPath("$.terms", is(UPDATE_MEMBER_TERMS))) .andExpect(jsonPath("$.profileImageUrl", containsString(testMember.getProfileImageKey()))) .andExpect(jsonPath("$.gender", is(testMember.getGender().name()))) .andExpect(jsonPath("$.birth", is(testMember.getBirth().toString()))); @@ -115,7 +113,7 @@ void updateMemberSuccessTest() throws Exception { @Test @DisplayName("PUT /member without Authorization JWT Cookie returns 401") void putMemberWithoutAuthHeader() throws Exception { - MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(UPDATE_MEMBER_NICKNAME, UPDATE_MEMBER_TERMS); + MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(UPDATE_MEMBER_NICKNAME); String jsonRequest = objectMapper.writeValueAsString(memberUpdateRequest); mockMvc.perform(put("/member/me") diff --git a/src/test/java/org/fontory/fontorybe/integration/member/controller/RegistrationControllerIntegrationTest.java b/src/test/java/org/fontory/fontorybe/integration/member/controller/RegistrationControllerIntegrationTest.java index 79e4fa8..da4f5a8 100644 --- a/src/test/java/org/fontory/fontorybe/integration/member/controller/RegistrationControllerIntegrationTest.java +++ b/src/test/java/org/fontory/fontorybe/integration/member/controller/RegistrationControllerIntegrationTest.java @@ -105,7 +105,7 @@ void checkDuplicateTrueTest() throws Exception { @Test @DisplayName("POST /register - add member success with valid Authorization header") void addMemberSuccessTest() throws Exception { - InitMemberInfoRequest initMemberInfoRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest initMemberInfoRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); String jsonRequest = objectMapper.writeValueAsString(initMemberInfoRequest); MockMultipartFile jsonPart = new MockMultipartFile( "req", diff --git a/src/test/java/org/fontory/fontorybe/integration/member/service/MemberUpdateServiceIntegrationTest.java b/src/test/java/org/fontory/fontorybe/integration/member/service/MemberUpdateServiceIntegrationTest.java index b0b7391..c4b5b30 100644 --- a/src/test/java/org/fontory/fontorybe/integration/member/service/MemberUpdateServiceIntegrationTest.java +++ b/src/test/java/org/fontory/fontorybe/integration/member/service/MemberUpdateServiceIntegrationTest.java @@ -85,7 +85,6 @@ void getOrThrowByIdTest() { () -> assertThat(foundMember.getNickname()).isEqualTo(TEST_MEMBER_NICKNAME), () -> assertThat(foundMember.getGender()).isEqualTo(TEST_MEMBER_GENDER), () -> assertThat(foundMember.getProvideId()).isEqualTo(TEST_PROVIDE_ID), - () -> assertThat(foundMember.getTerms()).isEqualTo(TEST_MEMBER_TERMS), () -> assertThat(foundMember.getProfileImageKey()).isEqualTo(TEST_MEMBER_PROFILE_KEY), () -> assertThat(foundMember.getCreatedAt()).isNotNull(), () -> assertThat(foundMember.getUpdatedAt()).isNotNull(), @@ -104,7 +103,7 @@ void getOrThrowByIdTestX() { @Test @DisplayName("member - create success test") void createTest() { - InitMemberInfoRequest initNewMemberRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest initNewMemberRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); ProvideCreateDto newProvideCreateDto = new ProvideCreateDto(NEW_MEMBER_PROVIDER, NEW_MEMBER_PROVIDED_ID, NEW_MEMBER_EMAIL); Provide createdProvide = provideService.create(newProvideCreateDto); Member createdMember = create(initNewMemberRequest, createdProvide); @@ -115,7 +114,6 @@ void createTest() { () -> assertThat(createdMember.getNickname()).isEqualTo(NEW_MEMBER_NICKNAME), () -> assertThat(createdMember.getGender()).isEqualTo(NEW_MEMBER_GENDER), () -> assertThat(createdMember.getBirth()).isEqualTo(NEW_MEMBER_BIRTH), - () -> assertThat(createdMember.getTerms()).isEqualTo(NEW_MEMBER_TERMS), () -> assertThat(createdMember.getProfileImageKey()).isEqualTo(NEW_MEMBER_PROFILE_KEY), () -> assertThat(createdMember.getCreatedAt()).isNotNull(), () -> assertThat(createdMember.getUpdatedAt()).isNotNull() @@ -130,11 +128,11 @@ void createDuplicateNicknameTest() { Provide createdProvide1 = provideService.create(provideCreateDto1); Provide createdProvide2 = provideService.create(provideCreateDto2); // 첫 번째 회원 생성 - InitMemberInfoRequest initNewMemberRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest initNewMemberRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); create(initNewMemberRequest, createdProvide1); // 동일 닉네임으로 또 회원 생성 시 예외 발생 - InitMemberInfoRequest duplicateInitNewMemberInfoRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest duplicateInitNewMemberInfoRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); assertThatThrownBy( () -> create(duplicateInitNewMemberInfoRequest, createdProvide2)) .isExactlyInstanceOf(MemberDuplicateNameExistsException.class); @@ -145,7 +143,7 @@ void createDuplicateNicknameTest() { void updateTest() { // 기존에 존재하는 회원(TEST_MEMBER_ID) 조회 Member member = memberLookupService.getOrThrowById(TEST_MEMBER_ID); - MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(UPDATE_MEMBER_NICKNAME, UPDATE_MEMBER_TERMS); + MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(UPDATE_MEMBER_NICKNAME); // 업데이트 요청: 단일 회원 ID만 전달 Member updatedMember = memberUpdateService.update(TEST_MEMBER_ID, memberUpdateRequest); @@ -157,7 +155,6 @@ void updateTest() { () -> assertThat(updatedMember.getProvideId()).isEqualTo(member.getProvideId()), () -> assertThat(updatedMember.getNickname()).isEqualTo(UPDATE_MEMBER_NICKNAME), () -> assertThat(updatedMember.getProfileImageKey()).isEqualTo(member.getProfileImageKey()), - () -> assertThat(updatedMember.getTerms()).isEqualTo(UPDATE_MEMBER_TERMS), () -> assertThat(updatedMember.getUpdatedAt()).isAfter(member.getUpdatedAt()) ); } @@ -173,13 +170,13 @@ void updateDuplicateNicknameTest() { // 두 회원을 각각 생성 String uniqueNickname1 = UUID.randomUUID().toString(); String uniqueNickname2 = UUID.randomUUID().toString(); - InitMemberInfoRequest initNewMemberInfoRequestDto1 = new InitMemberInfoRequest(uniqueNickname1, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); - InitMemberInfoRequest initNewMemberInfoRequestDto2 = new InitMemberInfoRequest(uniqueNickname2, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest initNewMemberInfoRequestDto1 = new InitMemberInfoRequest(uniqueNickname1, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); + InitMemberInfoRequest initNewMemberInfoRequestDto2 = new InitMemberInfoRequest(uniqueNickname2, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); Member member1 = create(initNewMemberInfoRequestDto1, createdProvide1); create(initNewMemberInfoRequestDto2, createdProvide2); // member1의 닉네임을 이미 존재하는 이름(uniqueNickname2)으로 업데이트 시도하면 예외 발생 - MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(uniqueNickname2, UPDATE_MEMBER_TERMS); + MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(uniqueNickname2); Long member1Id = member1.getId(); assertThatThrownBy( @@ -190,7 +187,7 @@ void updateDuplicateNicknameTest() { @Test @DisplayName("member - update fail test caused by member not found") void updateNonExistentMemberTest() { - MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(UPDATE_MEMBER_NICKNAME, UPDATE_MEMBER_TERMS); + MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(UPDATE_MEMBER_NICKNAME); assertThatThrownBy( () -> memberUpdateService.update(nonExistentId, memberUpdateRequest)) .isExactlyInstanceOf(MemberNotFoundException.class); @@ -203,7 +200,7 @@ void disableTest() { ProvideCreateDto provideCreateDto = new ProvideCreateDto(Provider.GOOGLE, UUID.randomUUID().toString(), UUID.randomUUID().toString()); Provide createdProvide = provideService.create(provideCreateDto); - InitMemberInfoRequest initNewMemberRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest initNewMemberRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); Member member = create(initNewMemberRequest, createdProvide); // 회원 비활성화 요청 (단일 ID) @@ -218,7 +215,7 @@ void disableAlreadyDisabledTest() { ProvideCreateDto provideCreateDto = new ProvideCreateDto(Provider.GOOGLE, UUID.randomUUID().toString(), UUID.randomUUID().toString()); Provide createdProvide = provideService.create(provideCreateDto); - InitMemberInfoRequest initNewMemberRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest initNewMemberRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); Member member = create(initNewMemberRequest, createdProvide); // 최초 비활성화 처리 diff --git a/src/test/java/org/fontory/fontorybe/unit/file/FileRequestMapperTest.java b/src/test/java/org/fontory/fontorybe/unit/file/FileRequestMapperTest.java index da1a3e3..6868b60 100644 --- a/src/test/java/org/fontory/fontorybe/unit/file/FileRequestMapperTest.java +++ b/src/test/java/org/fontory/fontorybe/unit/file/FileRequestMapperTest.java @@ -108,8 +108,7 @@ private static InitMemberInfoRequest createMemberRequest(String nickname) { return new InitMemberInfoRequest( nickname, Gender.MALE, - LocalDate.of(2025, 1, 26), - true + LocalDate.of(2025, 1, 26) ); } diff --git a/src/test/java/org/fontory/fontorybe/unit/file/FileServiceTest.java b/src/test/java/org/fontory/fontorybe/unit/file/FileServiceTest.java index c9057cc..58daa13 100644 --- a/src/test/java/org/fontory/fontorybe/unit/file/FileServiceTest.java +++ b/src/test/java/org/fontory/fontorybe/unit/file/FileServiceTest.java @@ -71,8 +71,7 @@ private static InitMemberInfoRequest createMemberRequest(String nickname) { return new InitMemberInfoRequest( nickname, Gender.MALE, - LocalDate.of(2025, 1, 26), - true + LocalDate.of(2025, 1, 26) ); } diff --git a/src/test/java/org/fontory/fontorybe/unit/member/controller/ProfileControllerTest.java b/src/test/java/org/fontory/fontorybe/unit/member/controller/ProfileControllerTest.java index 0871ca4..ba3706b 100644 --- a/src/test/java/org/fontory/fontorybe/unit/member/controller/ProfileControllerTest.java +++ b/src/test/java/org/fontory/fontorybe/unit/member/controller/ProfileControllerTest.java @@ -31,7 +31,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.fontory.fontorybe.TestConstants.*; -import static org.fontory.fontorybe.TestConstants.UPDATE_MEMBER_TERMS; import static org.junit.jupiter.api.Assertions.assertAll; class ProfileControllerTest { @@ -111,8 +110,7 @@ void disableAlreadyDisabledMemberTest() { void testUpdateMember() { //given MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest( - UPDATE_MEMBER_NICKNAME, - UPDATE_MEMBER_TERMS + UPDATE_MEMBER_NICKNAME ); //when @@ -124,7 +122,6 @@ void testUpdateMember() { () -> assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK), () -> assertThat(body).isNotNull(), () -> assertThat(body.getNickname()).isEqualTo(UPDATE_MEMBER_NICKNAME), - () -> assertThat(body.getTerms()).isEqualTo(UPDATE_MEMBER_TERMS), () -> assertThat(body.getProfileImageUrl()).isEqualTo(cloudStorageService.getProfileImageUrl(testMember.getProfileImageKey())) ); } @@ -134,7 +131,7 @@ void testUpdateMember() { void updateMemberNonExistentTest() { // given UserPrincipal nonExistentUserPrincipal = new UserPrincipal(NON_EXIST_ID); - MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(TestConstants.UPDATE_MEMBER_NICKNAME, UPDATE_MEMBER_TERMS); + MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(TestConstants.UPDATE_MEMBER_NICKNAME); // when & then assertThatThrownBy(() -> profileController.updateMember(nonExistentUserPrincipal, memberUpdateRequest, mockFiles)) diff --git a/src/test/java/org/fontory/fontorybe/unit/member/service/MemberUpdateServiceTest.java b/src/test/java/org/fontory/fontorybe/unit/member/service/MemberUpdateServiceTest.java index f119132..a2a7e0f 100644 --- a/src/test/java/org/fontory/fontorybe/unit/member/service/MemberUpdateServiceTest.java +++ b/src/test/java/org/fontory/fontorybe/unit/member/service/MemberUpdateServiceTest.java @@ -71,7 +71,6 @@ void getOrThrownByIdTest() { () -> assertThat(foundMember.getNickname()).isEqualTo(TEST_MEMBER_NICKNAME), () -> assertThat(foundMember.getGender()).isEqualTo(TEST_MEMBER_GENDER), () -> assertThat(foundMember.getProvideId()).isEqualTo(testMemberProvideId), - () -> assertThat(foundMember.getTerms()).isEqualTo(TEST_MEMBER_TERMS), () -> assertThat(foundMember.getProfileImageKey()).isNotEqualTo(DEFAULT_PROFILE_KEY), () -> assertThat(foundMember.getCreatedAt()).isNotNull(), () -> assertThat(foundMember.getUpdatedAt()).isNotNull(), @@ -114,7 +113,7 @@ void createTest() { ProvideCreateDto provideCreateDto = new ProvideCreateDto(NEW_MEMBER_PROVIDER, NEW_MEMBER_PROVIDED_ID, NEW_MEMBER_EMAIL); Provide createdProvide = testContainer.provideService.create(provideCreateDto); - InitMemberInfoRequest initNewMemberRequestDto = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest initNewMemberRequestDto = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); Member createdMember = testContainer.create(initNewMemberRequestDto, createdProvide); assertAll( @@ -123,7 +122,6 @@ void createTest() { () -> assertThat(createdMember.getNickname()).isEqualTo(NEW_MEMBER_NICKNAME), () -> assertThat(createdMember.getGender()).isEqualTo(NEW_MEMBER_GENDER), () -> assertThat(createdMember.getBirth()).isEqualTo(NEW_MEMBER_BIRTH), - () -> assertThat(createdMember.getTerms()).isEqualTo(NEW_MEMBER_TERMS), () -> assertThat(createdMember.getProfileImageKey()).isNotEqualTo(DEFAULT_PROFILE_KEY), () -> assertThat(createdMember.getCreatedAt()).isNotNull(), () -> assertThat(createdMember.getUpdatedAt()).isNotNull() @@ -139,11 +137,11 @@ void createDuplicateNicknameTest() { Provide createdProvide1 = testContainer.provideService.create(provideCreateDto1); Provide createdProvide2 = testContainer.provideService.create(provideCreateDto2); - InitMemberInfoRequest initNewMemberRequestDto = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest initNewMemberRequestDto = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); testContainer.create(initNewMemberRequestDto, createdProvide1); // 동일 닉네임으로 또 회원 생성 시 예외 발생 - InitMemberInfoRequest duplicateInitNewMemberInfoRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest duplicateInitNewMemberInfoRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); assertThatThrownBy( () -> testContainer.create(duplicateInitNewMemberInfoRequest, createdProvide2)) .isExactlyInstanceOf(MemberDuplicateNameExistsException.class); @@ -154,7 +152,7 @@ void createDuplicateNicknameTest() { void updateTest() { Long requestMemberId = testMemberId; Member member = memberLookupService.getOrThrowById(testMemberId); - MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(UPDATE_MEMBER_NICKNAME, UPDATE_MEMBER_TERMS); + MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(UPDATE_MEMBER_NICKNAME); Member updatedMember = memberUpdateService.update(requestMemberId, memberUpdateRequest); assertAll( @@ -165,7 +163,6 @@ void updateTest() { () -> assertThat(updatedMember.getProvideId()).isEqualTo(member.getProvideId()), () -> assertThat(updatedMember.getNickname()).isEqualTo(UPDATE_MEMBER_NICKNAME), () -> assertThat(updatedMember.getProfileImageKey()).isEqualTo(member.getProfileImageKey()), - () -> assertThat(updatedMember.getTerms()).isEqualTo(UPDATE_MEMBER_TERMS), () -> assertThat(updatedMember.getUpdatedAt()).isAfter(member.getUpdatedAt()) ); } @@ -181,13 +178,13 @@ void updateDuplicateNicknameTest() { String uniqueNickname1 = UUID.randomUUID().toString(); String uniqueNickname2 = UUID.randomUUID().toString(); - InitMemberInfoRequest initNewMemberRequestDto1 = new InitMemberInfoRequest(uniqueNickname1, Gender.MALE, NEW_MEMBER_BIRTH, TEST_MEMBER_TERMS); - InitMemberInfoRequest initNewMemberRequestDto2 = new InitMemberInfoRequest(uniqueNickname2, Gender.FEMALE, NEW_MEMBER_BIRTH, TEST_MEMBER_TERMS); + InitMemberInfoRequest initNewMemberRequestDto1 = new InitMemberInfoRequest(uniqueNickname1, Gender.MALE, NEW_MEMBER_BIRTH); + InitMemberInfoRequest initNewMemberRequestDto2 = new InitMemberInfoRequest(uniqueNickname2, Gender.FEMALE, NEW_MEMBER_BIRTH); Member member1 = testContainer.create(initNewMemberRequestDto1, createdProvide1); testContainer.create(initNewMemberRequestDto2, createdProvide2); // member1의 닉네임을 이미 존재하는 이름으로 업데이트 시도하면 예외 발생 - MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(uniqueNickname2, UPDATE_MEMBER_TERMS); + MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(uniqueNickname2); assertThatThrownBy( () -> memberUpdateService.update(member1.getId(), memberUpdateRequest)) .isExactlyInstanceOf(MemberDuplicateNameExistsException.class); @@ -201,8 +198,8 @@ void createProvideMemberMoreThanOneTest() { String uniqueNickname1 = UUID.randomUUID().toString(); String uniqueNickname2 = UUID.randomUUID().toString(); - InitMemberInfoRequest initNewMemberRequestDto1 = new InitMemberInfoRequest(uniqueNickname1, Gender.MALE, NEW_MEMBER_BIRTH, TEST_MEMBER_TERMS); - InitMemberInfoRequest initNewMemberRequestDto2 = new InitMemberInfoRequest(uniqueNickname2, Gender.MALE, NEW_MEMBER_BIRTH, TEST_MEMBER_TERMS); + InitMemberInfoRequest initNewMemberRequestDto1 = new InitMemberInfoRequest(uniqueNickname1, Gender.MALE, NEW_MEMBER_BIRTH); + InitMemberInfoRequest initNewMemberRequestDto2 = new InitMemberInfoRequest(uniqueNickname2, Gender.MALE, NEW_MEMBER_BIRTH); testContainer.create(initNewMemberRequestDto1, createdProvide); assertThatThrownBy( @@ -214,7 +211,7 @@ void createProvideMemberMoreThanOneTest() { @DisplayName("member - update fail test caused by member not found") void updateNonExistentMemberTest() { // 존재하지 않는 회원(-1L)을 대상으로 업데이트 시도 시 예외 발생 - MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(UPDATE_MEMBER_NICKNAME, UPDATE_MEMBER_TERMS); + MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(UPDATE_MEMBER_NICKNAME); assertThatThrownBy( () -> memberUpdateService.update(nonExistentId, memberUpdateRequest)) .isExactlyInstanceOf(MemberNotFoundException.class); @@ -226,15 +223,14 @@ void updateNoNicknameChangeTest() { // 닉네임 변경 없이 다른 정보만 업데이트하는 경우 Member member = memberLookupService.getOrThrowById(testMemberId); // 업데이트 DTO에서 기존 닉네임 그대로 사용 - MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(member.getNickname(), UPDATE_MEMBER_TERMS); + MemberUpdateRequest memberUpdateRequest = new MemberUpdateRequest(member.getNickname()); // 같은 닉네임을 사용하더라도 본인의 정보이므로 중복 체크가 통과되어 업데이트 성공해야 함 Member updatedMember = memberUpdateService.update(member.getId(), memberUpdateRequest); assertAll( () -> assertThat(updatedMember.getId()).isEqualTo(member.getId()), () -> assertThat(updatedMember.getNickname()).isEqualTo(member.getNickname()), - () -> assertThat(updatedMember.getProfileImageKey()).isEqualTo(member.getProfileImageKey()), - () -> assertThat(updatedMember.getTerms()).isEqualTo(UPDATE_MEMBER_TERMS) + () -> assertThat(updatedMember.getProfileImageKey()).isEqualTo(member.getProfileImageKey()) ); } @@ -254,7 +250,7 @@ void disableTest() { ProvideCreateDto provideCreateDto = new ProvideCreateDto(NEW_MEMBER_PROVIDER, NEW_MEMBER_PROVIDED_ID, NEW_MEMBER_EMAIL); Provide createdProvide = testContainer.provideService.create(provideCreateDto); - InitMemberInfoRequest initNewMemberRequestDto = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest initNewMemberRequestDto = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); Member member = testContainer.create(initNewMemberRequestDto, createdProvide); // 회원 비활성화 @@ -272,7 +268,7 @@ void disableAlreadyDisabledTest() { ProvideCreateDto provideCreateDto = new ProvideCreateDto(NEW_MEMBER_PROVIDER, NEW_MEMBER_PROVIDED_ID, NEW_MEMBER_EMAIL); Provide createdProvide = testContainer.provideService.create(provideCreateDto); - InitMemberInfoRequest initNewMemberRequestDto = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest initNewMemberRequestDto = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); Member member = testContainer.create(initNewMemberRequestDto, createdProvide); // 회원 비활성화 diff --git a/src/test/java/org/fontory/fontorybe/unit/mock/FakeMemberRepository.java b/src/test/java/org/fontory/fontorybe/unit/mock/FakeMemberRepository.java index 49fec4f..82c33f4 100644 --- a/src/test/java/org/fontory/fontorybe/unit/mock/FakeMemberRepository.java +++ b/src/test/java/org/fontory/fontorybe/unit/mock/FakeMemberRepository.java @@ -23,7 +23,6 @@ public Member save(Member member) { .nickname(member.getNickname()) .gender(member.getGender()) .birth(member.getBirth()) - .terms(member.getTerms()) .profileImageKey(member.getProfileImageKey()) .provideId(member.getProvideId()) .status(member.getStatus()) @@ -39,7 +38,6 @@ public Member save(Member member) { .nickname(member.getNickname()) .gender(member.getGender()) .birth(member.getBirth()) - .terms(member.getTerms()) .profileImageKey(member.getProfileImageKey()) .provideId(member.getProvideId()) .status(member.getStatus()) diff --git a/src/test/java/org/fontory/fontorybe/unit/mock/TestContainer.java b/src/test/java/org/fontory/fontorybe/unit/mock/TestContainer.java index 8e556b7..786e652 100644 --- a/src/test/java/org/fontory/fontorybe/unit/mock/TestContainer.java +++ b/src/test/java/org/fontory/fontorybe/unit/mock/TestContainer.java @@ -139,7 +139,6 @@ public TestContainer() { memberDefaults = new MemberDefaults( LocalDate.of(1999, 12, 31), - false, DEFAULT_PROFILE_KEY); fileService = FileServiceImpl.builder() @@ -231,7 +230,7 @@ public Member create(InitMemberInfoRequest initNewMemberInfoRequest, Provide pro public Provide testMemberProvide; public Provide newMemberProvide; - public final InitMemberInfoRequest newInitMemberInfoRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + public final InitMemberInfoRequest newInitMemberInfoRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); public final ProvideCreateDto newMemberProvideCreateDto = new ProvideCreateDto(NEW_MEMBER_PROVIDER, NEW_MEMBER_PROVIDED_ID, NEW_MEMBER_EMAIL); public Member createNotInitedMember() { @@ -241,13 +240,13 @@ public Member createNotInitedMember() { public Member createTestMember() { testMemberProvide = provideService.create(testMemberProvideCreateDto); - InitMemberInfoRequest initMemberInfoRequest = new InitMemberInfoRequest(TEST_MEMBER_NICKNAME, TEST_MEMBER_GENDER, TEST_MEMBER_BIRTH, TEST_MEMBER_TERMS); + InitMemberInfoRequest initMemberInfoRequest = new InitMemberInfoRequest(TEST_MEMBER_NICKNAME, TEST_MEMBER_GENDER, TEST_MEMBER_BIRTH); return create(initMemberInfoRequest, testMemberProvide); } public Member createNewMember() { newMemberProvide = provideService.create(newMemberProvideCreateDto); - InitMemberInfoRequest initNewMemberInfoRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH, NEW_MEMBER_TERMS); + InitMemberInfoRequest initNewMemberInfoRequest = new InitMemberInfoRequest(NEW_MEMBER_NICKNAME, NEW_MEMBER_GENDER, NEW_MEMBER_BIRTH); return create(initNewMemberInfoRequest, newMemberProvide); } } diff --git a/src/test/resources/sql/createFileTestData.sql b/src/test/resources/sql/createFileTestData.sql index 2f048e6..69c7524 100644 --- a/src/test/resources/sql/createFileTestData.sql +++ b/src/test/resources/sql/createFileTestData.sql @@ -3,8 +3,8 @@ truncate table `member`; truncate table `provide`; -- Test member data -insert into `member` (`member_id`, `nickname`, `gender`, `birth`, `terms`, `profile_image_key`, `provide_id`, `status`,`created_at`, `updated_at`) -values (999, 'existMemberNickName', 'MALE', '2025-01-26', 1, 'existMemberProfileImage', 999, 'ACTIVATE', NOW(), NOW()); +insert into `member` (`member_id`, `nickname`, `gender`, `birth`, `profile_image_key`, `provide_id`, `status`,`created_at`, `updated_at`) +values (999, 'existMemberNickName', 'MALE', '2025-01-26', 'existMemberProfileImage', 999, 'ACTIVATE', NOW(), NOW()); -- Test provide data insert into `provide` (`provide_id`, `provider`, `provided_id`, `email`, `member_id`) diff --git a/src/test/resources/sql/createFontTestData.sql b/src/test/resources/sql/createFontTestData.sql index 58d0018..6e42ddc 100644 --- a/src/test/resources/sql/createFontTestData.sql +++ b/src/test/resources/sql/createFontTestData.sql @@ -26,11 +26,11 @@ INSERT INTO `font` ( '2025-04-08 10:00:00' ); -insert into `member` (`member_id`, `nickname`, `gender`, `birth`, `terms`, `profile_image_key`, `provide_id`, `status`, `created_at`, `updated_at`) -values (999, 'existMemberNickName', 'MALE', '2025-01-26', 1, 'existMemberProfileImage', 999, 'ACTIVATE','1922-09-18 19:11:00.000000', '1922-09-18 19:11:00.000000'); +insert into `member` (`member_id`, `nickname`, `gender`, `birth`, `profile_image_key`, `provide_id`, `status`, `created_at`, `updated_at`) +values (999, 'existMemberNickName', 'MALE', '2025-01-26', 'existMemberProfileImage', 999, 'ACTIVATE','1922-09-18 19:11:00.000000', '1922-09-18 19:11:00.000000'); -insert into `member` (`member_id`, `nickname`, `gender`, `birth`, `terms`, `profile_image_key`, `provide_id`, `status`, `created_at`, `updated_at`) -values (1, 'createdMemberNickName', 'MALE', '2025-01-26', 1, 'existMemberProfileImage', 1, 'ACTIVATE','1922-09-18 19:11:00.000000', '1922-09-18 19:11:00.000000'); +insert into `member` (`member_id`, `nickname`, `gender`, `birth`, `profile_image_key`, `provide_id`, `status`, `created_at`, `updated_at`) +values (1, 'createdMemberNickName', 'MALE', '2025-01-26', 'existMemberProfileImage', 1, 'ACTIVATE','1922-09-18 19:11:00.000000', '1922-09-18 19:11:00.000000'); insert into `provide` (`provide_id`, `provider`, `provided_id`, `email`, `member_id`) values (999, 'GOOGLE', 'test_provided_id', 'test_email', 999); diff --git a/src/test/resources/sql/createMemberTestData.sql b/src/test/resources/sql/createMemberTestData.sql index 224330d..eebb305 100644 --- a/src/test/resources/sql/createMemberTestData.sql +++ b/src/test/resources/sql/createMemberTestData.sql @@ -1,8 +1,8 @@ truncate table `member`; truncate table `provide`; -insert into `member` (`member_id`, `nickname`, `gender`, `birth`, `terms`, `profile_image_key`, `provide_id`, `status`,`created_at`, `updated_at`) -values (999, 'testMemberNickName', 'MALE', '2025-01-26', 1, 'testMemberProfileImage', 1, 'ACTIVATE','1922-09-18 19:11:00.000000', '1922-09-18 19:11:00.000000'); +insert into `member` (`member_id`, `nickname`, `gender`, `birth`, `profile_image_key`, `provide_id`, `status`,`created_at`, `updated_at`) +values (999, 'testMemberNickName', 'MALE', '2025-01-26', 'testMemberProfileImage', 1, 'ACTIVATE','1922-09-18 19:11:00.000000', '1922-09-18 19:11:00.000000'); insert into `provide` (`provide_id`, `provider`, `provided_id`, `email`, `member_id`) values (1, 'GOOGLE', 'testMemberProvidedId', 'testMemberEmail', 999); \ No newline at end of file