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

회원 탈퇴 기능 구현 #162

Merged
merged 2 commits into from
Jul 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.RequestBody;
Expand Down Expand Up @@ -50,4 +51,15 @@ public ResponseEntity<Void> changeNickname(
return ResponseEntity.ok().build();
}

@Operation(summary = "회원 탈퇴", description = "서비스를 탈퇴한다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "회원 탈퇴 성공"),
@ApiResponse(responseCode = "404", description = "존재하지 않는 회원")
})
@DeleteMapping("/me/delete")
public ResponseEntity<Void> deleteMember(@Auth final Member member) {
memberService.deleteMember(member);
return ResponseEntity.noContent().build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private Member(
public static Member from(final KakaoMemberResponse response) {
final NicknameNumberGenerator nicknameNumberGenerator = new NicknameNumberGenerator();
return Member.builder()
.nickname("익명의 손님" + nicknameNumberGenerator.generate())
.nickname("익명의손님" + nicknameNumberGenerator.generate())
.gender(Gender.valueOf(response.kakaoAccount().gender().toUpperCase()))
.ageRange(response.kakaoAccount().ageRange())
.birthday(response.kakaoAccount().birthday())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,11 @@ private void validateExistentNickname(final String nickname) {
}
}

@Transactional
public void deleteMember(final Member member) {
final Member existentMember = memberRepository.findById(member.getId())
.orElseThrow(() -> new NotFoundException(MemberExceptionType.NONEXISTENT_MEMBER));
memberRepository.delete(existentMember);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,77 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willDoNothing;

import com.votogether.domain.member.dto.MemberInfoResponse;
import com.votogether.domain.member.dto.MemberNicknameUpdateRequest;
import com.votogether.domain.member.entity.Gender;
import com.votogether.domain.member.entity.Member;
import com.votogether.domain.member.entity.SocialType;
import com.votogether.domain.member.service.MemberService;
import com.votogether.fixtures.MemberFixtures;
import com.votogether.global.jwt.TokenPayload;
import com.votogether.global.jwt.TokenProcessor;
import io.restassured.http.ContentType;
import io.restassured.module.mockmvc.RestAssuredMockMvc;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.web.context.WebApplicationContext;

@Import(TokenProcessor.class)
@WebMvcTest(MemberController.class)
class MemberControllerTest {

@MockBean
MemberService memberService;

@Autowired
@MockBean
TokenProcessor tokenProcessor;

@BeforeEach
void setUp() {
void setUp(final WebApplicationContext webApplicationContext) {
RestAssuredMockMvc.standaloneSetup(new MemberController(memberService));
RestAssuredMockMvc.webAppContextSetup(webApplicationContext);
}

@Test
@DisplayName("회원 정보를 조회한다.")
void findMemberInfo() {
void findMemberInfo() throws Exception {
// given
Member member = Member.builder()
.nickname("저문")
.gender(Gender.MALE)
.ageRange("20~29")
.socialId("abc123")
.socialType(SocialType.KAKAO)
.birthday("0101")
.point(1234)
.build();
TokenPayload tokenPayload = new TokenPayload(1L, 1L, 1L);
MemberInfoResponse memberInfoResponse = new MemberInfoResponse(
"저문",
1234,
0,
0
);

given(tokenProcessor.resolveToken(anyString())).willReturn("token");
given(tokenProcessor.parseToken(anyString())).willReturn(tokenPayload);
given(memberService.findById(anyLong())).willReturn(member);
given(memberService.findMemberInfo(any(Member.class))).willReturn(memberInfoResponse);

// when
MemberInfoResponse response = RestAssuredMockMvc
.given().log().all()
.headers(HttpHeaders.AUTHORIZATION, "Bearer token")
.when().get("/members/me")
.then().log().all()
.extract()
Expand All @@ -75,44 +94,72 @@ class ChangeNickname {

@Test
@DisplayName("변경에 성공하면 200을 반환한다.")
void changeNicknameSuccess() {
void changeNicknameSuccess() throws Exception {
// given
String nicknameToChange = "jeomxon";
MemberNicknameUpdateRequest memberNicknameUpdateRequest = new MemberNicknameUpdateRequest(nicknameToChange);
TokenPayload tokenPayload = new TokenPayload(1L, 1L, 1L);

given(tokenProcessor.resolveToken(anyString())).willReturn("token");
given(tokenProcessor.parseToken(anyString())).willReturn(tokenPayload);
given(memberService.findById(anyLong())).willReturn(MemberFixtures.FEMALE_20.get());
willDoNothing().given(memberService).changeNickname(any(Member.class), anyString());

// when, then
RestAssuredMockMvc
.given().log().all()
.headers(HttpHeaders.AUTHORIZATION, "Bearer token")
.contentType(ContentType.JSON)
.body(memberNicknameUpdateRequest)
.when().patch("/members/me/nickname")
.then().log().all()
.statusCode(HttpStatus.OK.value())
.extract();
.statusCode(HttpStatus.OK.value());
}

@Test
@DisplayName("변경에 실패하면 400을 반환한다.")
void changeNicknameFail() {
void changeNicknameFail() throws Exception {
// given
String nicknameToChange = "";
MemberNicknameUpdateRequest memberNicknameUpdateRequest = new MemberNicknameUpdateRequest(nicknameToChange);
TokenPayload tokenPayload = new TokenPayload(1L, 1L, 1L);

given(tokenProcessor.resolveToken(anyString())).willReturn("token");
given(tokenProcessor.parseToken(anyString())).willReturn(tokenPayload);
given(memberService.findById(anyLong())).willReturn(MemberFixtures.FEMALE_20.get());
willDoNothing().given(memberService).changeNickname(any(Member.class), anyString());

// when, then
RestAssuredMockMvc
.given().log().all()
.headers(HttpHeaders.AUTHORIZATION, "Bearer token")
.contentType(ContentType.JSON)
.body(memberNicknameUpdateRequest)
.when().patch("/members/me/nickname")
.then().log().all()
.statusCode(HttpStatus.BAD_REQUEST.value())
.extract();
.statusCode(HttpStatus.BAD_REQUEST.value());
}

}

@Test
@DisplayName("회원 탈퇴에 성공하면 204를 반환한다.")
void deleteMember() throws Exception {
// given
TokenPayload tokenPayload = new TokenPayload(1L, 1L, 1L);

given(tokenProcessor.resolveToken(anyString())).willReturn("token");
given(tokenProcessor.parseToken(anyString())).willReturn(tokenPayload);
given(memberService.findById(anyLong())).willReturn(MemberFixtures.FEMALE_20.get());
willDoNothing().given(memberService).deleteMember(MemberFixtures.FEMALE_20.get());

// when, then
RestAssuredMockMvc
.given().log().all()
.headers(HttpHeaders.AUTHORIZATION, "Bearer token")
.when().delete("/members/me/delete")
.then().log().all()
.statusCode(HttpStatus.NO_CONTENT.value());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,17 @@ void changeNicknameEqualToPrevious() {

}

@Test
@DisplayName("회원 탈퇴를 성공한다.")
void deleteMember() {
// given
Member member = memberRepository.save(MemberFixtures.MALE_20.get());

// when
memberService.deleteMember(member);

// then
assertThat(memberRepository.findAll()).isEmpty();
}

}