Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[BE] Feature/#399 내 정보(회원 닉네임) 수정 API 구현 #408

Merged
merged 15 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions backend/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,19 @@

- 핀 상세 조회

#### 유저
#### 회원

- 유저 핀 생성
- 회원 핀 생성

- 유저 핀 정보 수정
- 회원 핀 정보 수정
- name, description 만 수정 가능하다.
- description 은 1000자 까지만 가능하다.

- 유저 핀 삭제
- 회원 핀 삭제
- Delete 는 Soft Delete

---

- 유저 핀 목록 조회
- 회원 핀 목록 조회
- 페이지 네이션 (무한 스크롤, 일단 15개)

4 changes: 2 additions & 2 deletions backend/src/docs/asciidoc/bookmark.adoc
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
== 즐겨찾기

=== 토픽을 유저의 즐겨찾기에 추가
=== 토픽을 회원의 즐겨찾기에 추가

operation::bookmark-controller-test/add-topic-in-bookmark[snippets='http-request,http-response']


=== 유저의 토픽 즐겨찾기 삭제
=== 회원의 토픽 즐겨찾기 삭제

operation::bookmark-controller-test/delete-topic-in-bookmark[snippets='http-request,http-response']
14 changes: 7 additions & 7 deletions backend/src/docs/asciidoc/member.adoc
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
== 유저
== 회원

=== 유저 목록 조회
=== 회원 목록 조회

operation::member-controller-test/find-all-member[snippets='http-request,http-response']

=== 유저 단일 조회
=== 회원 단일 조회

operation::member-controller-test/find-member-by-id[snippets='http-request,http-response']

=== 유저의 나의 지도 목록 조회
=== 회원의 나의 지도 목록 조회

operation::member-controller-test/find-my-all-topics[snippets='http-request,http-response']

=== 유저의 나의 핀 목록 조회
=== 회원의 나의 핀 목록 조회

operation::member-controller-test/find-my-all-pins[snippets='http-request,http-response']

=== 유저의 모아보기 조회
=== 회원의 모아보기 조회

operation::member-controller-test/find-all-topics-in-atlas[snippets='http-request,http-response']

=== 유저의 즐겨찾기 조회
=== 회원의 즐겨찾기 조회

operation::member-controller-test/find-all-topics-in-bookmark[snippets='http-request,http-response']
4 changes: 2 additions & 2 deletions backend/src/docs/asciidoc/permission.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ operation::permission-controller-test/add-permission[snippets='http-request,http

operation::permission-controller-test/delete-permission[snippets='http-request,http-response']

=== 토픽에 권한을 가진 유저 목록 조회
=== 토픽에 권한을 가진 회원 목록 조회

operation::permission-controller-test/find-all-topic-permissions[snippets='http-request,http-response']

=== 토픽에 권한을 가진 유저 단일 조회
=== 토픽에 권한을 가진 회원 단일 조회

operation::permission-controller-test/find-permission-by-id[snippets='http-request,http-response']
2 changes: 1 addition & 1 deletion backend/src/docs/asciidoc/pin.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ operation::pin-controller-test/find-all[snippets='http-request,http-response']

operation::pin-controller-test/find-by-id[snippets='http-request,http-response']

=== 멤버별 핀 목록 조회
=== 회원별 핀 목록 조회

operation::pin-controller-test/find-all-pins-by-member-id[snippets='http-request,http-response']

Expand Down
2 changes: 1 addition & 1 deletion backend/src/docs/asciidoc/topic.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ operation::topic-controller-test/find-all-by-order-by-updated-at-desc[snippets='

operation::topic-controller-test/find-all-best-topics[snippets='http-request,http-response']

=== 멤버별 토픽 목록 조회
=== 회원별 토픽 목록 조회

operation::topic-controller-test/find-all-topics-by-member-id[snippets='http-request,http-response']

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.mapbefine.mapbefine.member.application;

import com.mapbefine.mapbefine.auth.domain.AuthMember;
import com.mapbefine.mapbefine.member.domain.Member;
import com.mapbefine.mapbefine.member.domain.MemberRepository;
import com.mapbefine.mapbefine.member.dto.request.MemberUpdateRequest;
import com.mapbefine.mapbefine.member.exception.MemberErrorCode;
import com.mapbefine.mapbefine.member.exception.MemberException.MemberConflictException;
import java.util.NoSuchElementException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class MemberCommandService {

private final MemberRepository memberRepository;

public MemberCommandService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}

public void updateInfoById(AuthMember authMember, MemberUpdateRequest request) {
Member member = findMemberById(authMember.getMemberId());
String nickName = request.nickName();

validateNicknameDuplicated(nickName);

member.update(nickName);
}

private Member findMemberById(Long memberId) {
return memberRepository.findById(memberId)
.orElseThrow(() -> new NoSuchElementException("findMemberById; memberId=" + memberId));
}
Comment on lines +32 to +35
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

커스텀 예외 MemberNotFoundException 구현하지 않았나요 !?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#405 (comment)

쥬니 pr 코드리뷰로 남긴 내용과 연결되어서 링크로 남깁니다 !

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저 댓글이 이 의미였군요 이해했슴돠


private void validateNicknameDuplicated(String nickName) {
if (memberRepository.existsByMemberInfoNickName(nickName)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍

throw new MemberConflictException(MemberErrorCode.ILLEGAL_NICKNAME_ALREADY_EXISTS, nickName);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -98,21 +98,14 @@ private static String createNickname(String nickname) {
private static String createNicknameSuffix() {
return randomUUID()
.toString()
.replaceAll("-", "")
.replace("-", "")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 replaceAll 이랑 기능은 똑같은데 성능이 더 좋군요! 처음 알았슴둥

.substring(0, DEFAULT_NICKNAME_SUFFIX_LENGTH);
}

public void update(
String nickName,
String email,
String imageUrl
String nickName
) {
memberInfo = MemberInfo.of(
nickName,
email,
imageUrl,
memberInfo.getRole()
);
memberInfo = memberInfo.createUpdatedMemberInfo(nickName);
}

public void addTopic(Topic topic) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class MemberInfo {
@Column(nullable = false, length = 20, unique = true)
private String nickName;

@Column(nullable = false, unique = true)
@Column(nullable = false)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굉장히 좋은 의견이군요!

private String email;

@Column(nullable = false)
Expand Down Expand Up @@ -93,6 +93,11 @@ private static void validateRole(Role role) {
}
}

public MemberInfo createUpdatedMemberInfo(String nickName) {

yoondgu marked this conversation as resolved.
Show resolved Hide resolved
return MemberInfo.of(nickName, this.email, this.imageUrl.getImageUrl(), this.role);
}

public String getImageUrl() {
return imageUrl.getImageUrl();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@

public interface MemberRepository extends JpaRepository<Member, Long> {

Optional<Member> findByMemberInfoEmail(String email);

boolean existsByMemberInfoEmail(String email);

Optional<Member> findByOauthIdOauthServerId(Long oauthServerId);
Optional<Member> findById(Long id);

Optional<Member> findByOauthId(OauthId oauthId);

boolean existsByMemberInfoNickName(String nickName);

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
public enum Role {

ADMIN("ROLE_ADMIN", "운영자"),
USER("ROLE_USER", "로그인 유저"),
USER("ROLE_USER", "로그인 회원"),
GUEST("ROLE_GUEST", "손님");

private final String key;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.mapbefine.mapbefine.member.dto.request;

public record MemberUpdateRequest(
String nickName
) {
}
yoondgu marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public enum MemberErrorCode {
ILLEGAL_EMAIL_NULL("05002", "이메일은 필수로 입력해야합니다."),
ILLEGAL_EMAIL_PATTERN("05003", "올바르지 않은 이메일 형식입니다."),
MEMBER_NOT_FOUND("05400", "존재하지 않는 회원입니다."),
ILLEGAL_NICKNAME_ALREADY_EXISTS("05900", "이미 존재하는 닉네임입니다."),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍👍👍👍👍👍👍👍👍👍👍👍👍

;

private final String code;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.mapbefine.mapbefine.member.exception;

import com.mapbefine.mapbefine.common.exception.BadRequestException;
import com.mapbefine.mapbefine.common.exception.ConflictException;
import com.mapbefine.mapbefine.common.exception.ErrorCode;
import com.mapbefine.mapbefine.common.exception.NotFoundException;

Expand All @@ -18,5 +19,11 @@ public MemberNotFoundException(MemberErrorCode errorCode, Long id) {
}
}

public static class MemberConflictException extends ConflictException {
public MemberConflictException(MemberErrorCode errorCode, String value) {
super(new ErrorCode<>(errorCode.getCode(), errorCode.getMessage(), value));
}
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,31 @@

import com.mapbefine.mapbefine.auth.domain.AuthMember;
import com.mapbefine.mapbefine.common.interceptor.LoginRequired;
import com.mapbefine.mapbefine.member.application.MemberCommandService;
import com.mapbefine.mapbefine.member.application.MemberQueryService;
import com.mapbefine.mapbefine.member.dto.request.MemberUpdateRequest;
import com.mapbefine.mapbefine.member.dto.response.MemberDetailResponse;
import com.mapbefine.mapbefine.member.dto.response.MemberResponse;
import com.mapbefine.mapbefine.pin.dto.response.PinResponse;
import com.mapbefine.mapbefine.topic.dto.response.TopicResponse;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/members")
public class MemberController {

private final MemberCommandService memberCommandService;
private final MemberQueryService memberQueryService;

public MemberController(MemberQueryService memberQueryService) {
public MemberController(MemberCommandService memberCommandService, MemberQueryService memberQueryService) {
this.memberCommandService = memberCommandService;
this.memberQueryService = memberQueryService;
}

Expand Down Expand Up @@ -72,4 +78,12 @@ public ResponseEntity<List<TopicResponse>> findAllTopicsInBookmark(AuthMember au
return ResponseEntity.ok(responses);
}

@LoginRequired
@PatchMapping("/my/profiles")
public ResponseEntity<Void> updateMyInfo(AuthMember authMember, @RequestBody MemberUpdateRequest request) {
memberCommandService.updateInfoById(authMember, request);

return ResponseEntity.ok().build();
}

}
2 changes: 1 addition & 1 deletion backend/src/main/resources/config
16 changes: 16 additions & 0 deletions backend/src/main/resources/data-default.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
INSERT INTO member (nick_name, email, image_url, role,
oauth_server_id, oauth_server_type,
created_at, updated_at)
VALUES ('dummyMember', 'dummy@gmail.com', 'https://map-befine-official.github.io/favicon.png', 'USER',
1L, 'KAKAO',
now(), now());

INSERT INTO topic (name, image_url, description,
permission_type, publicity,
member_id,
created_at, updated_at)
VALUES ('dummyTopic', 'https://map-befine-official.github.io/favicon.png', 'description',
'ALL_MEMBERS', 'PUBLIC',
1L,
now(), now())
;
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ void validateReadPermission_fail() {
}

@Test
@DisplayName("멤버 ID와 TopicId가 있을 경우, atlas에서 해당 topic을 비운다.")
@DisplayName("회원 ID와 TopicId가 있을 경우, atlas에서 해당 topic을 비운다.")
void remove_Success() {
Long topicId = topic.getId();
Long memberId = authMember.getMemberId();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.mapbefine.mapbefine.auth.infrastructure;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

@SpringBootTest(classes = JwtTokenProvider.class)
@TestPropertySource(locations = "classpath:application.yml")
class JwtTokenProviderTest {

@Autowired
private JwtTokenProvider jwtTokenProvider;

@Test
@DisplayName("payload를 받아 JWT 토큰을 생성한다.")
void createToken() {
String payload = "1";

String token = jwtTokenProvider.createToken(payload);

assertThat(jwtTokenProvider.getPayload(token))
.isEqualTo(payload);
}

yoondgu marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class BookmarkIntegrationTest extends IntegrationTest {
private BookmarkRepository bookmarkRepository;

@Test
@DisplayName("유저가 토픽을 즐겨찾기 목록에 추가하면, 201을 반환한다.")
@DisplayName("회원이 토픽을 즐겨찾기 목록에 추가하면, 201을 반환한다.")
void addTopicInBookmark_Success() {
//given
Member creator = MemberFixture.create("member", "member@naver.com", Role.USER);
Expand Down Expand Up @@ -63,7 +63,7 @@ void addTopicInBookmark_Success() {
}

@Test
@DisplayName("유저의 즐겨찾기 토픽을 삭제하면, 204를 반환한다.")
@DisplayName("회원의 즐겨찾기 토픽을 삭제하면, 204를 반환한다.")
void deleteTopicInBookmark_Success() {
//given
Member creator = MemberFixture.create("member", "member@naver.com", Role.USER);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class BookmarkCommandServiceTest {
private TestEntityManager testEntityManager;

@Test
@DisplayName("다른 유저의 토픽을 즐겨찾기에 추가할 수 있다.")
@DisplayName("다른 회원의 토픽을 즐겨찾기에 추가할 수 있다.")
public void addTopicInBookmark_Success() {
//given
Member creator = MemberFixture.create(
Expand Down Expand Up @@ -72,7 +72,7 @@ public void addTopicInBookmark_Success() {
}

@Test
@DisplayName("권한이 없는 다른 유저의 토픽을 즐겨찾기에 추가할 수 없다.")
@DisplayName("권한이 없는 다른 회원의 토픽을 즐겨찾기에 추가할 수 없다.")
public void addTopicInBookmark_Fail1() {
//given
Member creator = MemberFixture.create(
Expand Down
Loading