์ด์ ํ์ ์๋น์ค ๋ง์ง๋ง์ ๋๋ค!
์ปจํธ๋กค๋ฌ๋ฅผ ๊ฐ๋ฐํ์ฌ, Http ์์ฒญ์ ๋ํด ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ ์ ์๋๋ก ์ปจํธ๋กค๋ฌ๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
- ์ํ๋ฆฌํฐ๋ฅผ ์ด์ฉํ JSON ๋ฐ์ดํฐ๋ก ๋ก๊ทธ์ธ (์๋ฃ)
- JWT๋ฅผ ์ด์ฉํ ์ธ์ฆ (์๋ฃ)
- ๋๋ฉ์ธ, ํ ์ด๋ธ ์ค๊ณ, ์ํฐํฐ ์์ฑ (์๋ฃ)
- ๋๊ธ ์ญ์ ๋ก์ง ๊ตฌํ (์๋ฃ)
- ํ์๊ฐ์ + ์ ๋ณด์์ ๋ฑ ํ์ ์๋น์ค ๊ตฌํ (์งํ ์ค)
- ๊ฒ์ํ ์๋น์ค ๊ตฌํ
- ๋๊ธ ์๋น์ค ๊ตฌํ (1๋๊ธ -> *(๋ฌดํ) ๋๋๊ธ ๊ตฌ์กฐ)
- ์์ธ ์ฒ๋ฆฌ
- ์์ธ ๋ฉ์ธ์ง ๊ตญ์ ํ
- ์นดํ ๊ณ ๋ฆฌ๋ณ ๊ฒ์ํ ๋ถ๋ฅ
- ๊ฒ์๊ธ ํ์ด์ง
- ๋์ ์ธ ๊ฒ์ ์กฐ๊ฑด์ ์ฌ์ฉํ ๊ฒ์
- ์ฌ์ฉ์ ๊ฐ ์ชฝ์ง ๊ธฐ๋ฅ
- ๋ฌดํ ์ชฝ์ง ์คํฌ๋กค
- ๊ฒ์๋ฌผ & ๋๊ธ์ ๋ํ ์๋
- ์ชฝ์ง์ ๋ํ ์๋
- ์ ์ํ ์ฌ์ฉ์ ๊ฐ ์ค์๊ฐ ์ฑํ
- ํ์๊ฐ์ ์ ๊ฒ์ฆ(์: XX๋ํ๊ต XX๊ณผ๊ฐ ์๋๋ฉด ๊ฐ์ ํ ์ ์๊ฒ)
- Swagger๋ฅผ ์ฌ์ฉํ API ๋ฌธ์ ๋ง๋ค๊ธฐ
- ์ ๊ณ & ๋ธ๋๋ฆฌ์คํธ ๊ธฐ๋ฅ
- AOP๋ฅผ ํตํ ๋ก๊ทธ
- ์ด๋๋ฏผ ํ์ด์ง
- ์บ์
- ๋ฐฐํฌ (+ ๋ฌด์ค๋จ ๋ฐฐํฌ)
- ๋ฐฐํฌ ์๋ํ
- ํฌํธ์ ์ด๋ํฐ ์ค๊ณ๋ฅผ ๋ฐ๋ฅด๋ ํจํค์ง ๊ตฌ์กฐ ์ค๊ณํ๊ธฐ
- ...
MemberController
@RestController
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
/**
* ํ์๊ฐ์
*/
@PostMapping("/signUp")
@ResponseStatus(HttpStatus.OK)
public void signUp(@Valid @RequestBody MemberSignUpDto memberSignUpDto) throws Exception {
memberService.signUp(memberSignUpDto);
}
/**
* ํ์์ ๋ณด์์
*/
@PutMapping("/member")
@ResponseStatus(HttpStatus.OK)
public void updateBasicInfo(@Valid @RequestBody MemberUpdateDto memberUpdateDto) throws Exception {
memberService.update(memberUpdateDto);
}
/**
* ๋น๋ฐ๋ฒํธ ์์
*/
@PutMapping("/member/password")
@ResponseStatus(HttpStatus.OK)
public void updatePassword(@Valid @RequestBody UpdatePasswordDto updatePasswordDto) throws Exception {
memberService.updatePassword(updatePasswordDto.checkPassword(),updatePasswordDto.toBePassword());
}
/**
* ํ์ํํด
*/
@DeleteMapping("/member")
@ResponseStatus(HttpStatus.OK)
public void withdraw(@Valid @RequestBody MemberWithdrawDto memberWithdrawDto) throws Exception {
memberService.withdraw(memberWithdrawDto.checkPassword());
}
/**
* ํ์์ ๋ณด์กฐํ
*/
@GetMapping("/member/{id}")
public ResponseEntity getInfo(@Valid @PathVariable("id") Long id) throws Exception {
MemberInfoDto info = memberService.getInfo(id);
return new ResponseEntity(info, HttpStatus.OK);
}
/**
* ๋ด์ ๋ณด์กฐํ
*/
@GetMapping("/member")
public ResponseEntity getMyInfo(HttpServletResponse response) throws Exception {
MemberInfoDto info = memberService.getMyInfo();
return new ResponseEntity(info, HttpStatus.OK);
}
}
์ค๋ช
@RestController๋ @Controller + @ResponseBody๋ก ๋ทฐ๋ฅผ ๋ฐํํ๋ ๊ฒ์ด ์๋
๋ฌธ์์ด์ response์ Body์ ์์ฑํ์ฌ ์ ์กํด์ค๋๋ค.
@ResponseStatus(HttpStatus.OK)๋ ํญ์ ์ํ์ฝ๋๋ฅผ 200์ผ๋ก ๋ฐํํ๋๋ก ๋ง๋ค์์ต๋๋ค.
์ํ์ฝ๋๋ฅผ ํ์์ ๋ฐ๋ผ์ ๋ค๋ฅด๊ฒ ์ค ์๋ ์์ง๋ง, ์ ๋ ์ด๋ฒ ํ๋ก์ ํธ์์๋ ๋ชจ๋ ์ํ์ฝ๋๋ฅผ 200์ผ๋ก ์ค์ ํ์ฌ ๋ฐํํ ๊ฒ์ด๊ธฐ์ OK๋ก ๊ณ ์ ํด ์ฃผ์์ต๋๋ค.
ํ์ ์์ธ์ฒ๋ฆฌ ๋ถ๋ถ์์ ๋ค๋ฅธ ์ค๋ฅ๋ ๋ชจ๋ 200์ผ๋ก ๋ฐ๊ฟ์ฃผ๋๋ก ํ๊ฒ ์ต๋๋ค.
ํ๋์ ๋ํ ๊ฒ์ฆ์ ์ํด @Valid๋ฅผ ์ฌ์ฉํ์์ต๋๋ค.
ํ๋ก ํธ์์ 1์ฐจ์ ์ผ๋ก ๊ฒ์ฆ์ ํ์ฌ ๊ฐ์ด ํ์์ ๋ง์ง ์์ผ๋ฉด ์์ฒญ์ ๋ณด๋ด์ง ๋ชปํ๋๋ก ์ฝ๋๋ฅผ ๊ตฌํํ์ํ ์ง๋ง,
์ ์์ ์ธ ์๋๋ก Postman๋ฑ์ ํตํด ํ๋์ ๊ฐ์ ์ฑ์ฐ์ง ์๊ณ ์์ฒญ์ ๋ณด๋ด ์์ธ ์ํฉ์ ๋ง๋ค์ด ๋ผ ์ ์๊ธฐ์,
์๋ฒ์์๋ ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ๊ฒ์ฆ์ ์ถ๊ฐํด ์ฃผ์์ต๋๋ค.
DTO
DTO๊ฐ ์กฐ๊ธ ์ถ๊ฐ๋๊ณ @Valid๋ฅผ ํตํด ๊ฒ์ฆํ๋ ๊ฒ๋ ์ถ๊ฐ๋์์ต๋๋ค. ํจํค์ง ์์น๋ ์ด์ ๊ณผ ๊ฐ์ต๋๋ค.
MemberInfoDto
@Data
@NoArgsConstructor
public class MemberInfoDto {
private String name;
private String nickName;
private String username;
private Integer age;
@Builder
public MemberInfoDto(Member member) {
this.name = member.getName();
this.nickName = member.getNickName();
this.username = member.getUsername();
this.age = member.getAge();
}
}
MemberSignUpDto
public record MemberSignUpDto(@NotBlank(message = "์์ด๋๋ฅผ ์
๋ ฅํด์ฃผ์ธ์") @Size(min = 7, max = 25, message = "์์ด๋๋ 7~25์ ๋ด์ธ๋ก ์
๋ ฅํด์ฃผ์ธ์")
String username,
@NotBlank(message = "๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์")
@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,30}$",
message = "๋น๋ฐ๋ฒํธ๋ 8~30 ์๋ฆฌ์ด๋ฉด์ 1๊ฐ ์ด์์ ์ํ๋ฒณ, ์ซ์, ํน์๋ฌธ์๋ฅผ ํฌํจํด์ผํฉ๋๋ค.")
String password,
@NotBlank(message = "์ด๋ฆ์ ์
๋ ฅํด์ฃผ์ธ์") @Size(min=2, message = "์ฌ์ฉ์ ์ด๋ฆ์ด ๋๋ฌด ์งง์ต๋๋ค.")
@Pattern(regexp = "^[A-Za-z๊ฐ-ํฃ]+$", message = "์ฌ์ฉ์ ์ด๋ฆ์ ํ๊ธ ๋๋ ์ํ๋ฒณ๋ง ์
๋ ฅํด์ฃผ์ธ์.")
String name,
@NotBlank(message = "๋๋ค์์ ์
๋ ฅํด์ฃผ์ธ์.")
@Size(min=2, message = "๋๋ค์์ด ๋๋ฌด ์งง์ต๋๋ค.")
@NotBlank String nickName,
@NotNull(message = "๋์ด๋ฅผ ์
๋ ฅํด์ฃผ์ธ์")
@Range(min = 0, max = 150)
Integer age) {
public Member toEntity() {
return Member.builder().username(username).password(password).name(name).nickName(nickName).age(age).build();
}
}
@Valid๋ฅผ ํตํด ํด๋น ํ๋๋ค์ ๊ฒ์ฆํฉ๋๋ค.
์ฌ์ค message๋ ์์ด๋ ๋๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ฑํ ํด๋น message ์์ด๋, ์ ๋น์ด ํ๋์ ๊ฐ์ ์ฑ์ฐ์ง ์์ผ๋ฉด ํ๋ก ํธ๋จ์์ ์์ฒญ์ ๋ณด๋ด์ง ๋ชปํ๊ฒ๋ ๊ตฌ์ฑํ์ฌ, ์๋ฒ๋ @Valid๋ฅผ ํตํด ์์์น ๋ชปํ ์ค๋ฅ๋ฅผ ๋ฐฉ์ง๋ง ํ๋ฉด ๋๋ค๊ณ ์๊ฐํฉ๋๋ค๋ง.. ๋จ์ง ์ ๊ทํํ์ ๊ณต๋ถ์ @Valid๋ค์ ๊ณต๋ถํ๊ธฐ ์ํด ์ฌ์ฉํ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ํด๋น message๋ฅผ ํตํด, ์ข ๋ ์๊ตฌ์ฌํญ์ ๋ช ํํ๊ฒ ์ ์ ์๋ค๋ ์ฅ์ ๋ ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
MemberUpdateDto
public record MemberUpdateDto(Optional<String> name, Optional<String> nickName,
Optional<Integer> age) {
}
MemberWithdrawDto
public record MemberWithdrawDto(@NotBlank(message = "๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์")
String checkPassword) {
}
UpdatePasswordDto
public record UpdatePasswordDto(@NotBlank(message = "๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์")
String checkPassword,
@NotBlank(message = "๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์")
@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,30}$",
message = "๋น๋ฐ๋ฒํธ๋ 8~30 ์๋ฆฌ์ด๋ฉด์ 1๊ฐ ์ด์์ ์ํ๋ฒณ, ์ซ์, ํน์๋ฌธ์๋ฅผ ํฌํจํด์ผํฉ๋๋ค.")
String toBePassword) {
}
์ถ๊ฐ๋ก ๊ฒ์ฆ ์์ธ์ ์ํ์ฝ๋๋ฅผ 200์ผ๋ก ๋ฐ๊พธ์ด์ฃผ๊ธฐ ์ํด, ์์๋ก ControllerAdvice๋ฅผ ์์ฑํ์์ต๋๋ค.
์์น๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
ExceptionAdvice
@RestControllerAdvice
public class ExceptionAdvice {
@ExceptionHandler(Exception.class)
public ResponseEntity handleMemberEx(Exception exception){
return new ResponseEntity(HttpStatus.OK);
}
}
์ค๋ช
@RestControllerAdvice๋ @ControllerAdvice์ @ResponseBody๋ฅผ ํฉ์น ๊ฒ์ ๋๋ค.
@ControllerAdvice๋ ๋ชจ๋ @Controller์์ ๋ฐ์ํ๋ ์์ธ๋ฅผ ์ฒ๋ฆฌํด์ค ์ ์๋๋ก ๋์์ฃผ๋ ์ญํ ์ ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ @ExceptionHandler๋ฅผ ํตํด, ์ด๋ค ์์ธ๋ฅผ ์ก์์ ์ฒ๋ฆฌํ ์ง ๋ช ์ํ ์ ์์ต๋๋ค.
์ถ๊ฐ๋ก Filter์์ ๋ฐ์ํ๋ ์์ธ๋ ControllerAdvice๊น์ง ๋์ด์ค์ง ์์ต๋๋ค.
๋ฐ๋ผ์ ์คํ๋ง ์ํ๋ฆฌํฐ ํํฐ์์ ๋ฐ์ํ ๊ถํ ์๋ ์์ธ๋ผ๋์ง ๋ฑ์, ๋ฐ๋ก Filter์ handler๋ฅผ ์ค์ ํด ์ฃผ์ด ์ฒ๋ฆฌํด์ฃผ์ด์ผ ํฉ๋๋ค.
ํ์ฌ๋ ํํฐ์ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ ํธ๋ค๋ฌ๋ฅผ ๋ง๋ค์ง ์์๊ธฐ์ ๊ถํ์ด ์๋ ๊ฒฝ์ฐ 403 ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
ํ์ ์ด๋ฅผ ๋ชจ๋ ๋ค๋ฃจ์ด 200์ผ๋ก ๋ฐํํ๋ ์ฝ๋๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
ํ ์คํธ์ฝ๋
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
class MemberControllerTest {
@Autowired MockMvc mockMvc;
@Autowired EntityManager em;
@Autowired MemberService memberService;
@Autowired MemberRepository memberRepository;
ObjectMapper objectMapper = new ObjectMapper();
@Autowired
PasswordEncoder passwordEncoder;
private static String SIGN_UP_URL = "/signUp";
private String username = "username";
private String password = "password1234@";
private String name = "shinD";
private String nickName = "shinD cute";
private Integer age = 22;
private void clear(){
em.flush();
em.clear();
}
private void signUp(String signUpData) throws Exception {
mockMvc.perform(
post(SIGN_UP_URL)
.contentType(MediaType.APPLICATION_JSON)
.content(signUpData))
.andExpect(status().isOk());
}
@Value("${jwt.access.header}")
private String accessHeader;
private static final String BEARER = "Bearer ";
private String getAccessToken() throws Exception {
Map<String, String> map = new HashMap<>();
map.put("username",username);
map.put("password",password);
MvcResult result = mockMvc.perform(
post("/login")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(map)))
.andExpect(status().isOk()).andReturn();
return result.getResponse().getHeader(accessHeader);
}
@Test
public void ํ์๊ฐ์
_์ฑ๊ณต() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
//when
signUp(signUpData);
//then
Member member = memberRepository.findByUsername(username).orElseThrow(() -> new Exception("ํ์์ด ์์ต๋๋ค"));
assertThat(member.getName()).isEqualTo(name);
assertThat(memberRepository.findAll().size()).isEqualTo(1);
}
@Test
public void ํ์๊ฐ์
_์คํจ_ํ๋๊ฐ_์์() throws Exception {
//given
String noUsernameSignUpData = objectMapper.writeValueAsString(new MemberSignUpDto(null, password, name, nickName, age));
String noPasswordSignUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, null, name, nickName, age));
String noNameSignUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, null, nickName, age));
String noNickNameSignUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, null, age));
String noAgeSignUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, null));
//when, then
signUp(noUsernameSignUpData);//์์ธ๊ฐ ๋ฐ์ํ๋๋ผ๋ ์ํ์ฝ๋๋ 200
signUp(noPasswordSignUpData);//์์ธ๊ฐ ๋ฐ์ํ๋๋ผ๋ ์ํ์ฝ๋๋ 200
signUp(noNameSignUpData);//์์ธ๊ฐ ๋ฐ์ํ๋๋ผ๋ ์ํ์ฝ๋๋ 200
signUp(noNickNameSignUpData);//์์ธ๊ฐ ๋ฐ์ํ๋๋ผ๋ ์ํ์ฝ๋๋ 200
signUp(noAgeSignUpData);//์์ธ๊ฐ ๋ฐ์ํ๋๋ผ๋ ์ํ์ฝ๋๋ 200
assertThat(memberRepository.findAll().size()).isEqualTo(0);
}
@Test
public void ํ์์ ๋ณด์์ _์ฑ๊ณต() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
Map<String, Object> map = new HashMap<>();
map.put("name",name+"๋ณ๊ฒฝ");
map.put("nickName",nickName+"๋ณ๊ฒฝ");
map.put("age",age+1);
String updateMemberData = objectMapper.writeValueAsString(map);
//when
mockMvc.perform(
put("/member")
.header(accessHeader,BEARER+accessToken)
.contentType(MediaType.APPLICATION_JSON)
.content(updateMemberData))
.andExpect(status().isOk());
//then
Member member = memberRepository.findByUsername(username).orElseThrow(() -> new Exception("ํ์์ด ์์ต๋๋ค"));
assertThat(member.getName()).isEqualTo(name+"๋ณ๊ฒฝ");
assertThat(member.getNickName()).isEqualTo(nickName+"๋ณ๊ฒฝ");
assertThat(member.getAge()).isEqualTo(age+1);
assertThat(memberRepository.findAll().size()).isEqualTo(1);
}
@Test
public void ํ์์ ๋ณด์์ _์ํ๋ํ๋๋ง๋ณ๊ฒฝ_์ฑ๊ณต() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
Map<String, Object> map = new HashMap<>();
map.put("name",name+"๋ณ๊ฒฝ");
String updateMemberData = objectMapper.writeValueAsString(map);
//when
mockMvc.perform(
put("/member")
.header(accessHeader,BEARER+accessToken)
.contentType(MediaType.APPLICATION_JSON)
.content(updateMemberData))
.andExpect(status().isOk());
//then
Member member = memberRepository.findByUsername(username).orElseThrow(() -> new Exception("ํ์์ด ์์ต๋๋ค"));
assertThat(member.getName()).isEqualTo(name+"๋ณ๊ฒฝ");
assertThat(member.getNickName()).isEqualTo(nickName);
assertThat(member.getAge()).isEqualTo(age);
assertThat(memberRepository.findAll().size()).isEqualTo(1);
}
@Test
public void ๋น๋ฐ๋ฒํธ์์ _์ฑ๊ณต() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
Map<String, Object> map = new HashMap<>();
map.put("checkPassword",password);
map.put("toBePassword",password+"!@#@!#@!#");
String updatePassword = objectMapper.writeValueAsString(map);
//when
mockMvc.perform(
put("/member/password")
.header(accessHeader,BEARER+accessToken)
.contentType(MediaType.APPLICATION_JSON)
.content(updatePassword))
.andExpect(status().isOk());
//then
Member member = memberRepository.findByUsername(username).orElseThrow(() -> new Exception("ํ์์ด ์์ต๋๋ค"));
assertThat(passwordEncoder.matches(password, member.getPassword())).isFalse();
assertThat(passwordEncoder.matches(password+"!@#@!#@!#", member.getPassword())).isTrue();
}
@Test
public void ๋น๋ฐ๋ฒํธ์์ _์คํจ_๊ฒ์ฆ๋น๋ฐ๋ฒํธ๊ฐ_ํ๋ฆผ() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
Map<String, Object> map = new HashMap<>();
map.put("checkPassword",password+"1");
map.put("toBePassword",password+"!@#@!#@!#");
String updatePassword = objectMapper.writeValueAsString(map);
//when
mockMvc.perform(
put("/member/password")
.header(accessHeader,BEARER+accessToken)
.contentType(MediaType.APPLICATION_JSON)
.content(updatePassword))
.andExpect(status().isOk());
//then
Member member = memberRepository.findByUsername(username).orElseThrow(() -> new Exception("ํ์์ด ์์ต๋๋ค"));
assertThat(passwordEncoder.matches(password, member.getPassword())).isTrue();
assertThat(passwordEncoder.matches(password+"!@#@!#@!#", member.getPassword())).isFalse();
}
@Test
public void ๋น๋ฐ๋ฒํธ์์ _์คํจ_๋ฐ๊พธ๋ ค๋_๋น๋ฐ๋ฒํธ_ํ์_์ฌ๋ฐ๋ฅด์ง์์() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
Map<String, Object> map = new HashMap<>();
map.put("checkPassword",password);
map.put("toBePassword","123123");
String updatePassword = objectMapper.writeValueAsString(map);
//when
mockMvc.perform(
put("/member/password")
.header(accessHeader,BEARER+accessToken)
.contentType(MediaType.APPLICATION_JSON)
.content(updatePassword))
.andExpect(status().isOk());
//then
Member member = memberRepository.findByUsername(username).orElseThrow(() -> new Exception("ํ์์ด ์์ต๋๋ค"));
assertThat(passwordEncoder.matches(password, member.getPassword())).isTrue();
assertThat(passwordEncoder.matches("123123", member.getPassword())).isFalse();
}
@Test
public void ํ์ํํด_์ฑ๊ณต() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
Map<String, Object> map = new HashMap<>();
map.put("checkPassword",password);
String updatePassword = objectMapper.writeValueAsString(map);
//when
mockMvc.perform(
delete("/member")
.header(accessHeader,BEARER+accessToken)
.contentType(MediaType.APPLICATION_JSON)
.content(updatePassword))
.andExpect(status().isOk());
//then
assertThrows(Exception.class, () -> memberRepository.findByUsername(username).orElseThrow(() -> new Exception("ํ์์ด ์์ต๋๋ค")));
}
@Test
public void ํ์ํํด_์คํจ_๋น๋ฐ๋ฒํธํ๋ฆผ() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
Map<String, Object> map = new HashMap<>();
map.put("checkPassword",password+11);
String updatePassword = objectMapper.writeValueAsString(map);
//when
mockMvc.perform(
delete("/member")
.header(accessHeader,BEARER+accessToken)
.contentType(MediaType.APPLICATION_JSON)
.content(updatePassword))
.andExpect(status().isOk());
//then
Member member = memberRepository.findByUsername(username).orElseThrow(() -> new Exception("ํ์์ด ์์ต๋๋ค"));
assertThat(member).isNotNull();
}
@Test
public void ํ์ํํด_์คํจ_๊ถํ์ด์์() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
Map<String, Object> map = new HashMap<>();
map.put("checkPassword",password);
String updatePassword = objectMapper.writeValueAsString(map);
//when
mockMvc.perform(
delete("/member")
.header(accessHeader,BEARER+accessToken+"1")
.contentType(MediaType.APPLICATION_JSON)
.content(updatePassword))
.andExpect(status().isForbidden());
//then
Member member = memberRepository.findByUsername(username).orElseThrow(() -> new Exception("ํ์์ด ์์ต๋๋ค"));
assertThat(member).isNotNull();
}
@Test
public void ๋ด์ ๋ณด์กฐํ_์ฑ๊ณต() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
//when
MvcResult result = mockMvc.perform(
get("/member")
.characterEncoding(StandardCharsets.UTF_8)
.header(accessHeader, BEARER + accessToken))
.andExpect(status().isOk()).andReturn();
//then
Map<String, Object> map = objectMapper.readValue(result.getResponse().getContentAsString(), Map.class);
Member member = memberRepository.findByUsername(username).orElseThrow(() -> new Exception("ํ์์ด ์์ต๋๋ค"));
assertThat(member.getAge()).isEqualTo(map.get("age"));
assertThat(member.getUsername()).isEqualTo(map.get("username"));
assertThat(member.getName()).isEqualTo(map.get("name"));
assertThat(member.getNickName()).isEqualTo(map.get("nickName"));
}
@Test
public void ๋ด์ ๋ณด์กฐํ_์คํจ_JWT์์() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
//when,then
mockMvc.perform(
get("/member")
.characterEncoding(StandardCharsets.UTF_8)
.header(accessHeader, BEARER + accessToken+1))
.andExpect(status().isForbidden());
}
/**
* ํ์์ ๋ณด์กฐํ ์ฑ๊ณต
* ํ์์ ๋ณด์กฐํ ์คํจ -> ํ์์ด์์
* ํ์์ ๋ณด์กฐํ ์คํจ -> ๊ถํ์ด์์
*/
@Test
public void ํ์์ ๋ณด์กฐํ_์ฑ๊ณต() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
Long id = memberRepository.findAll().get(0).getId();
//when
MvcResult result = mockMvc.perform(
get("/member/"+id)
.characterEncoding(StandardCharsets.UTF_8)
.header(accessHeader, BEARER + accessToken))
.andExpect(status().isOk()).andReturn();
//then
Map<String, Object> map = objectMapper.readValue(result.getResponse().getContentAsString(), Map.class);
Member member = memberRepository.findByUsername(username).orElseThrow(() -> new Exception("ํ์์ด ์์ต๋๋ค"));
assertThat(member.getAge()).isEqualTo(map.get("age"));
assertThat(member.getUsername()).isEqualTo(map.get("username"));
assertThat(member.getName()).isEqualTo(map.get("name"));
assertThat(member.getNickName()).isEqualTo(map.get("nickName"));
}
@Test
public void ํ์์ ๋ณด์กฐํ_์คํจ_์๋ํ์์กฐํ() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
//when
MvcResult result = mockMvc.perform(
get("/member/2211")
.characterEncoding(StandardCharsets.UTF_8)
.header(accessHeader, BEARER + accessToken))
.andExpect(status().isOk()).andReturn();
//then
assertThat(result.getResponse().getContentAsString()).isEqualTo("");//๋น ๋ฌธ์์ด
}
@Test
public void ํ์์ ๋ณด์กฐํ_์คํจ_JWT์์() throws Exception {
//given
String signUpData = objectMapper.writeValueAsString(new MemberSignUpDto(username, password, name, nickName, age));
signUp(signUpData);
String accessToken = getAccessToken();
//when,then
mockMvc.perform(
get("/member/1")
.characterEncoding(StandardCharsets.UTF_8)
.header(accessHeader, BEARER + accessToken+1))
.andExpect(status().isForbidden());
}
}
์ด๋ ๊ฒ ์ปจํธ๋กค๋ฌ๊น์ง ๋ง๋ค์ด ๋ณด์์ต๋๋ค!
๋ค์์๋ ํ์ ์กฐํ ์ ํ์์ด ์๋ ๊ฒฝ์ฐ๋, ํ์๊ฐ์ ์ ์์ด๋๊ฐ ์ค๋ณต๋์์ ๋ ๋ฑ, ํ์ ๊ด๋ จํ์ฌ ๋ฐ์ํ ์์ธ๋ฅผ ์ฒ๋ฆฌํ๋ ํด๋์ค๋ฅผ ๋ง๋ค์ด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ ์ฒด ์ฝ๋๋ ๊นํ๋ธ์์ ํ์ธํ์ค ์ ์์ต๋๋ค.
https://github.com/ShinDongHun1/SpringBoot-Board-API