-
Notifications
You must be signed in to change notification settings - Fork 4
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
회원 정보 조회 기능 구현 #137
회원 정보 조회 기능 구현 #137
Changes from 8 commits
5501220
fa4c465
0274d09
b5cdfa1
914bcee
1e53e99
2bdaa04
00747bd
e24536e
369e81d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.votogether.domain.member.controller; | ||
|
||
import com.votogether.domain.member.dto.MemberInfoResponse; | ||
import com.votogether.domain.member.entity.Member; | ||
import com.votogether.domain.member.service.MemberService; | ||
import com.votogether.global.jwt.Auth; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@Tag(name = "회원", description = "회원 API") | ||
@RequiredArgsConstructor | ||
@RequestMapping("/members") | ||
@RestController | ||
public class MemberController { | ||
|
||
private final MemberService memberService; | ||
|
||
@Operation(summary = "회원 정보 조회", description = "회원 정보를 반환한다.") | ||
@ApiResponses({ | ||
@ApiResponse(responseCode = "200", description = "정보 조회 성공"), | ||
@ApiResponse(responseCode = "400", description = "올바르지 않은 요청"), | ||
}) | ||
@GetMapping("/me") | ||
public ResponseEntity<MemberInfoResponse> findMemberInfo(@Auth final Member member) { | ||
return ResponseEntity.ok(memberService.findMemberInfo(member)); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.votogether.domain.member.dto; | ||
|
||
public record MemberInfoResponse( | ||
String nickname, | ||
Integer point, | ||
int postCount, | ||
int voteCount | ||
) { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,11 @@ | ||
package com.votogether.domain.post.repository; | ||
|
||
import com.votogether.domain.member.entity.Member; | ||
import com.votogether.domain.post.entity.Post; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface PostRepository extends JpaRepository<Post, Long> { | ||
|
||
int countByMember(final Member member); | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package com.votogether.domain.member.controller; | ||
|
||
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.BDDMockito.given; | ||
|
||
import com.votogether.domain.member.dto.MemberInfoResponse; | ||
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.global.jwt.TokenProcessor; | ||
import io.restassured.module.mockmvc.RestAssuredMockMvc; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.DisplayName; | ||
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(TokenProcessor.class) | ||
@WebMvcTest(MemberController.class) | ||
class MemberControllerTest { | ||
|
||
@MockBean | ||
MemberService memberService; | ||
|
||
@Autowired | ||
TokenProcessor tokenProcessor; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
RestAssuredMockMvc.standaloneSetup(new MemberController(memberService)); | ||
} | ||
|
||
@Test | ||
@DisplayName("회원 정보를 조회한다.") | ||
void findMemberInfo() { | ||
// given | ||
Member member = Member.builder() | ||
.nickname("저문") | ||
.gender(Gender.MALE) | ||
.ageRange("20~29") | ||
.birthday("0101") | ||
.socialType(SocialType.KAKAO) | ||
.socialId("123123") | ||
.point(1234) | ||
.build(); | ||
|
||
MemberInfoResponse memberInfoResponse = new MemberInfoResponse( | ||
"저문", | ||
1234, | ||
0, | ||
0 | ||
); | ||
|
||
given(memberService.register(member)).willReturn(member); | ||
Member registeredMember = memberService.register(member); | ||
String token = tokenProcessor.generateToken(registeredMember); | ||
|
||
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() | ||
.as(MemberInfoResponse.class); | ||
|
||
// then | ||
assertAll( | ||
() -> assertThat(response.nickname()).isEqualTo("저문"), | ||
() -> assertThat(response.point()).isEqualTo(1234), | ||
() -> assertThat(response.postCount()).isEqualTo(0), | ||
() -> assertThat(response.voteCount()).isEqualTo(0) | ||
); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,11 +3,12 @@ | |
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import com.votogether.RepositoryTest; | ||
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.repository.MemberRepository; | ||
import com.votogether.domain.post.entity.Post; | ||
import com.votogether.domain.post.entity.PostBody; | ||
import com.votogether.fixtures.MemberFixtures; | ||
import java.time.LocalDateTime; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
|
@@ -17,30 +18,45 @@ | |
class PostRepositoryTest { | ||
|
||
@Autowired | ||
PostRepository postRepository; | ||
private PostRepository postRepository; | ||
|
||
@Autowired | ||
MemberRepository memberRepository; | ||
private MemberRepository memberRepository; | ||
|
||
@Test | ||
@DisplayName("Post를 저장한다") | ||
void save() { | ||
// given | ||
Member member = memberRepository.save(MemberFixtures.MALE_EARLY_10.get()); | ||
|
||
PostBody postBody = PostBody.builder() | ||
final PostBody postBody = PostBody.builder() | ||
.title("title") | ||
.content("content") | ||
.build(); | ||
|
||
Post post = Post.builder() | ||
final Member member = Member.builder() | ||
.gender(Gender.MALE) | ||
.point(0) | ||
.socialType(SocialType.KAKAO) | ||
.nickname("user1") | ||
.gender(Gender.MALE) | ||
.birthday("0718") | ||
.ageRange("10~14") | ||
.socialType(SocialType.KAKAO) | ||
.socialId("[email protected]") | ||
.ageRange("30~39") | ||
.birthday("0101") | ||
.point(0) | ||
.build(); | ||
|
||
final Post post = Post.builder() | ||
.member(member) | ||
.postBody(postBody) | ||
.deadline(LocalDateTime.of(2100, 7, 12, 0, 0)) | ||
.build(); | ||
|
||
memberRepository.save(member); | ||
|
||
// when | ||
Post savedPost = postRepository.save(post); | ||
final Post savedPost = postRepository.save(post); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 아벨의 코드인데 아마 conflict해결하면서 파일 자체가 포함된 것 같네요. conflict를 잘못 해결했는지 제가 작성한 테스트가 날아가버렸네요..ㅠㅠ 수정해서 추가할게요..! |
||
|
||
// then | ||
assertThat(savedPost).isNotNull(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -252,4 +252,39 @@ void findVoteCountByPostOptionIdGroupByAgeRangeAndGender() { | |
); | ||
} | ||
|
||
@Test | ||
@DisplayName("해당 회원이 투표한 개수를 반환한다.") | ||
void countByMember() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 해당 회원이 작성한 게시글 수를 검증하는 테스트를 말씀하신거라면 |
||
// given | ||
Member member = memberRepository.save(MemberFixtures.MALE_LATE_10.get()); | ||
Member writer = memberRepository.save(MemberFixtures.MALE_20.get()); | ||
Post post = postRepository.save( | ||
Post.builder() | ||
.member(writer) | ||
.postBody(PostBody.builder().title("title").content("content").build()) | ||
.deadline(LocalDateTime.of(2100, 7, 12, 0, 0)) | ||
.build() | ||
); | ||
PostOption postOption = postOptionRepository.save( | ||
PostOption.builder() | ||
.post(post) | ||
.sequence(1) | ||
.content("치킨") | ||
.build() | ||
); | ||
Vote vote = Vote.builder() | ||
.member(member) | ||
.postOption(postOption) | ||
.build(); | ||
|
||
memberRepository.save(member); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 헉.. 그러네요 수정했습니다~ |
||
voteRepository.save(vote); | ||
|
||
// when | ||
int numberOfVote = voteRepository.countByMember(member); | ||
|
||
// then | ||
assertThat(numberOfVote).isEqualTo(1); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2
맨 위의 3줄이랑 //when 에서 헤더에 토큰 값 설정해주는 코드가 없어도 테스트가 통과하더라구요
@WebMvcTest에서는 알규먼트리졸브랑 필터가 안사용되어지는거 같은데 어떡하면 좋을까요
.+ MemberService계층에 대한 테스트가 추가되면 좋을거같아요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
와우... 처음 알았어요...! 루쿠신...
엄청난걸 배워가네요!
삭제하면 좋을 것 같네요.
추가적으로 MemberService에 대한 테스트는 repository에 있는 내용을 단순 response객체에 담아주는 역할 밖에 없어서 따로 작성하지 않았어요. 이에 대해 루쿠는 어떻게 생각하시는지 궁금해요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋아요~ repository에 대한 테스트도 있으니 충분한거같습니다