Skip to content

Commit

Permalink
fix: nickname 검색 예외 처리 (escape) (#267)
Browse files Browse the repository at this point in the history
* fix: 공백, 특수문자 escape 처리

* fix: nickname null 예외 처리

* fix: spotlessApply

* fix: 닉네임 수정 시 공백 허용

* fix: 삼항 연산자 수정

* feat: 닉네임 검사에 따른 테스트 케이스 추가

* feat: 닉네임 Pattern validate message 추가

* fix: nickname Pattern message  는 -> 은으로 변경

* chore: gitkeep 삭제 (잠수함 패치)

* fix: nickname 유효성 공백 예외 처리 추가

* fix: spotlessApply
  • Loading branch information
char-yb authored Feb 4, 2024
1 parent e0f3cc3 commit 805bceb
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public ResponseEntity<Void> memberUsernameCheck(
return ResponseEntity.ok().build();
}

@Operation(summary = "닉네임 중복 체크", description = "닉네임 중복 체크를 진행합니다.")
@Operation(summary = "닉네임 유효성 체크", description = "닉네임 유효성 체크를 진행합니다.")
@PostMapping("/check-nickname")
public ResponseEntity<Void> memberNicknameCheck(
@Valid @RequestBody NicknameCheckRequest request) {
Expand All @@ -54,7 +54,8 @@ public ResponseEntity<Void> memberNicknameCheck(

@Operation(summary = "닉네임으로 회원 검색", description = "닉네임으로 회원을 검색합니다.")
@GetMapping("/search")
public List<MemberSearchResponse> memberNicknameSearch(@RequestParam String nickname) {
public List<MemberSearchResponse> memberNicknameSearch(
@RequestParam(required = false) String nickname) {
return memberService.searchMemberNickname(nickname);
}

Expand All @@ -76,8 +77,8 @@ public ResponseEntity<MemberSocialInfoResponse> memberSocialInfoFind() {
@Operation(summary = "회원 닉네임 변경", description = "회원 닉네임을 변경합니다.")
@PutMapping("/me/nickname")
public ResponseEntity<Void> memberNicknameUpdate(
@Valid @RequestBody NicknameUpdateRequest reqest) {
memberService.updateMemberNickname(reqest);
@Valid @RequestBody NicknameUpdateRequest request) {
memberService.updateMemberNickname(request);
return ResponseEntity.ok().build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ public void checkUsername(UsernameCheckRequest request) {
@Transactional(readOnly = true)
public void checkNickname(NicknameCheckRequest request) {
validateNicknameNotDuplicate(request.nickname());
if (validateNicknameText(request.nickname())) {
throw new CustomException(ErrorCode.MEMBER_INVALID_NICKNAME);
}
}

private boolean validateNicknameText(String nickname) {
return nickname == null || nickname.trim().isEmpty();
}

private void validateNicknameNotDuplicate(String nickname) {
Expand All @@ -73,8 +80,11 @@ private void validateNicknameNotDuplicate(String nickname) {
@Transactional(readOnly = true)
public List<MemberSearchResponse> searchMemberNickname(String nickname) {
final Member currentMember = memberUtil.getCurrentMember();
final String escapingNickname = escapeSpecialCharacters(nickname);

List<Member> members =
memberRepository.nicknameSearch(nickname, currentMember.getProfile().getNickname());
memberRepository.nicknameSearch(
escapingNickname, currentMember.getProfile().getNickname());
List<MemberRelation> memberRelationBySourceId =
memberRelationRepository.findAllBySourceIdAndTargetIn(
currentMember.getId(), members);
Expand Down Expand Up @@ -147,10 +157,10 @@ private void validateSocialInfoNotNull(Member member) {
}
}

public void updateMemberNickname(NicknameUpdateRequest reqest) {
public void updateMemberNickname(NicknameUpdateRequest request) {
final Member currentMember = memberUtil.getCurrentMember();
validateNicknameNotDuplicate(reqest.nickname());
currentMember.updateNickname(reqest.nickname());
validateNicknameNotDuplicate(request.nickname());
currentMember.updateNickname(escapeSpecialCharacters(request.nickname()));
}

private ImageFileExtension getImageFileExtension(Profile profile) {
Expand All @@ -174,4 +184,9 @@ public void updateFcmToken(UpdateFcmTokenRequest updateFcmTokenRequest) {
final Member currentMember = memberUtil.getCurrentMember();
currentMember.updateFcmToken(currentMember.getFcmInfo(), updateFcmTokenRequest.fcmToken());
}

private String escapeSpecialCharacters(String nickname) {
// 여기서 특수문자를 '_'로 대체할 수 있도록 정규표현식을 활용하여 구현
return nickname == null ? "" : nickname.replaceAll("[^0-9a-zA-Z가-힣 ]", "_");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.depromeet.domain.member.domain.Member;
import com.depromeet.domain.member.domain.OauthInfo;
import io.lettuce.core.dynamic.annotation.Param;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -20,6 +21,7 @@ public interface MemberRepository extends JpaRepository<Member, Long> {
Optional<Member> findByProfileNickname(String nickname);

@Query(
"SELECT m FROM Member m WHERE m.profile.nickname like %:searchNickname% AND m.profile.nickname != :myNickname")
List<Member> nicknameSearch(String searchNickname, String myNickname);
"SELECT m FROM Member m WHERE m.profile.nickname LIKE CONCAT('%', :searchNickname, '%') escape '_' AND m.profile.nickname != :myNickname")
List<Member> nicknameSearch(
@Param("searchNickname") String searchNickname, @Param("myNickname") String myNickname);
}
4 changes: 4 additions & 0 deletions src/main/java/com/depromeet/domain/member/domain/Profile.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.depromeet.domain.member.domain;

import jakarta.persistence.Embeddable;
import jakarta.validation.constraints.Pattern;
import lombok.*;

@Embeddable
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Profile {

@Pattern(regexp = "[^0-9a-zA-Z가-힣 ]", message = "올바르지 않은 닉네임 표현입니다.")
private String nickname;

@Getter private String profileImageUrl;

@Builder(access = AccessLevel.PRIVATE)
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public enum ErrorCode {
EXPIRED_JWT_TOKEN(HttpStatus.UNAUTHORIZED, "만료된 JWT 토큰입니다."),
MEMBER_ALREADY_REGISTERED(HttpStatus.CONFLICT, "이미 가입된 회원입니다."),
MEMBER_ALREADY_NICKNAME(HttpStatus.CONFLICT, "이미 존재하는 닉네임입니다."),
MEMBER_INVALID_NICKNAME(HttpStatus.BAD_REQUEST, "올바르지 않는 닉네임입니다."),
MEMBER_ALREADY_DELETED(HttpStatus.NOT_FOUND, "이미 탈퇴한 회원입니다."),
PASSWORD_NOT_MATCHES(HttpStatus.UNAUTHORIZED, "비밀번호가 일치하지 않습니다."),
ID_TOKEN_VERIFICATION_FAILED(HttpStatus.UNAUTHORIZED, "ID 토큰 검증에 실패했습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,64 @@ void setUp() {
assertFalse(responses.contains(currentMember.getProfile().getNickname()));
}

@Test
void 검색_키워드에_퍼센트_키워드가_들어왔을_때_NPE_무시_처리한다() {
// given
memberRepository.save(
Member.createNormalMember(Profile.createProfile("도모", "도모 이미지 URL")));
memberRepository.save(
Member.createNormalMember(Profile.createProfile("도모 바보", "testImageUrl")));

String searchNickname = "%";

// when
List<MemberSearchResponse> responses =
memberService.searchMemberNickname(searchNickname);

// then
assertEquals(0, responses.size());
}

@Test
void 검색_키워드에_공백에_따른_처리만_허용한다() {
// given
memberRepository.save(Member.createNormalMember(Profile.createProfile("바보", "도모 얼굴")));
memberRepository.save(
Member.createNormalMember(Profile.createProfile("도 모", "도모 이미지 URL")));
memberRepository.save(
Member.createNormalMember(Profile.createProfile("도모 바보", "testImageUrl")));
memberRepository.save(
Member.createNormalMember(Profile.createProfile(" 도모", "도모 잘생김")));
String searchNickname = " ";

// when
List<MemberSearchResponse> responses =
memberService.searchMemberNickname(searchNickname);

// then
assertEquals(3, responses.size());
}

@Test
void 검색_키워드에_특수문자_입력_시_정규식_예외처리를_한다() {
// given
memberRepository.save(
Member.createNormalMember(Profile.createProfile("#도모", "도모 이미지 URL")));
memberRepository.save(
Member.createNormalMember(Profile.createProfile("도모 바보#", "testImageUrl")));

memberRepository.save(
Member.createNormalMember(Profile.createProfile("#도모 바보#", "testImageUrl")));
String searchNickname = "#";

// when
List<MemberSearchResponse> responses =
memberService.searchMemberNickname(searchNickname);

// then
assertEquals(0, responses.size());
}

@Test
void 정렬조건은_일치하는경우_먼저보여주고_나머지는_사전순에_따른다() {
// given
Expand Down

0 comments on commit 805bceb

Please sign in to comment.