http.exceptionHandling()
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
.accessDeniedHandler(jwtAccessDenialHandler)
.and()
.authorizeRequests()
.antMatchers("/api/auth/sign_in", "/api/auth/join").permitAll()
.antMatchers("/api/auth/reissue").access("hasAuthority('USER') or hasAuthority('MANAGER') or hasAuthority('ADMIN')")
.antMatchers("/api/members/**").access("hasAuthority('USER') or hasAuthority('MANAGER') or hasAuthority('ADMIN')")
.and()
.apply(new JwtSecurityConfig(tokenProvider));
return http.build();
일단 SecurityConfig에 member에 대해서 다음과 같이 설정해주었다.
이후, 기존 MemberService의 search테스트를 그대로 가져와, 테스트메서드 구조만 조금 바꾸어주었다.
@Test
@DisplayName("토큰이 없으면, 401에러를 반환한다.")
public void searchNoToken_FAIL() throws Exception{
//given
SearchMemberDto searchMemberDto = SearchMemberDto.builder()
.username(null)
.email(null)
.nickname(null)
.build();
//expected
mvc.perform(MockMvcRequestBuilders.get("/api/members/search")
.contentType(MediaType.APPLICATION_JSON)
.content(makeJson(searchMemberDto)))
.andExpect(MockMvcResultMatchers.status().isUnauthorized())
.andDo(MockMvcResultHandlers.print());
}
@Test
@DisplayName("검색 파라미터가 전부 null이면 400에러와, 검색조건이 없음을 반환한다.")
public void searchAllNull_FAIL() throws Exception{
//given
TokenResponseDto tokenResponseDto = authService.signIn(SignInRequestDto.builder()
.username("test1")
.password("test1").build());
SearchMemberDto searchMemberDto = SearchMemberDto.builder()
.username(null)
.email(null)
.nickname(null)
.build();
//expected
mvc.perform(MockMvcRequestBuilders.get("/api/members/search")
.header("Authorization", "Bearer ".concat(tokenResponseDto.getAccessToken()))
.header("RefreshToken", "Bearer ".concat(tokenResponseDto.getRefreshToken()))
.contentType(MediaType.APPLICATION_JSON)
.content(makeJson(searchMemberDto)))
.andExpect(MockMvcResultMatchers.status().isBadRequest())
.andDo(MockMvcResultHandlers.print());
}
@Test
@DisplayName("test라는 아이디를 기준으로 1페이지를 검색하면 test1~test10이 출력된다.")
public void searchAll_Success() throws Exception{
//given
TokenResponseDto tokenResponseDto = authService.signIn(SignInRequestDto.builder()
.username("test1")
.password("test1").build());
SearchMemberDto searchMemberDto = SearchMemberDto.builder()
.username("test")
.email(null)
.nickname(null)
.build();
//expected
mvc.perform(MockMvcRequestBuilders.get("/api/members/search?page={}", 1)
.header("Authorization", "Bearer ".concat(tokenResponseDto.getAccessToken()))
.header("RefreshToken", "Bearer ".concat(tokenResponseDto.getRefreshToken()))
.contentType(MediaType.APPLICATION_JSON)
.content(makeJson(searchMemberDto)))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.success").value(true))
.andExpect(MockMvcResultMatchers.jsonPath("$.code").value(200))
.andExpect(MockMvcResultMatchers.jsonPath("$.result.data.content.length()").value(10))
.andExpect(MockMvcResultMatchers.jsonPath("$.result.data.content.[0].username").value("test1"))
.andDo(MockMvcResultHandlers.print());
}
이런식으로 만들어주었다(사실 코드 자체를 그대로 가져오는 것은, 컨트롤러 테스트방식과 서비스 테스트방식의 차이말고는 똑같기에 의미가 없다고 판단했다. 모든 테스트에 서비스 + 토큰의 경우 정도만 생각하면 된다. )
@Test
@DisplayName("회원 삭제를 성공하면 성공문구와 200코드를 반환한다.")
public void delete_Success() throws Exception{
//given
authService.registerNewMember(RegisterRequestDto.builder()
.username("test")
.nickname("test")
.email("test@test.com")
.password("test")
.passwordCheck("test").build());
TokenResponseDto tokenResponseDto = authService.signIn(SignInRequestDto.builder()
.username("test")
.password("test").build());
//expected
mvc.perform(MockMvcRequestBuilders.delete("/api/members/delete")
.header("Authorization", "Bearer ".concat(tokenResponseDto.getAccessToken()))
.header("RefreshToken", "Bearer ".concat(tokenResponseDto.getRefreshToken())))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.success").value(true))
.andExpect(MockMvcResultMatchers.jsonPath("$.code").value(200))
.andExpect(MockMvcResultMatchers.jsonPath("$.result.data").value("회원이 삭제되었습니다. 그동한 감사합니다."));
}
삭제에 대한 테스트도 만들었다.
회원 탈퇴가 필요할 수 있다고 판단했기 때문이다.
@Transactional
public String deleteMember(Member member){
memberRepository.findByUsername(member.getUsername()).orElseThrow(MemberNotFoundException::new);
memberRepository.delete(member);
return "회원이 삭제되었습니다. 그동한 감사합니다.";
}
삭제에 대한 서비스 로직도 간단하게 만들어주었다.
Member에 대해서도 마무리가 되었다.
물론, 나중에 다시 돌아올 수 있다.
왜냐하면, 게시판에서 마이페이지를 가면, 내가 쓴 게시물들이 나와야 한다.
나중에 Post에 대한 기능들을 만들면서, 이에 대해서도 Member로 돌아와 구현해야겠다.
'스프링 공부 > 게시판 프로젝트 만들기' 카테고리의 다른 글
[스프링] 36. MemberController.edit을 조금 다듬어서 테스트해보자. (0) | 2023.02.20 |
---|---|
[스프링] 35. AuthController.reissue 테스트부터 프로젝트 코드까지 (0) | 2023.02.20 |
[스프링] 34. AuthController.signIn을 테스트해보자. (0) | 2023.02.20 |
[스프링] 33. 잠깐 쉬면서 만들었던 것들을 리펙토링 한 과정을 요약해보자. (0) | 2023.02.16 |
[스프링] 32. MemberController.register 중복과 기타사유의 예외 테스트 (0) | 2023.02.12 |