Skip to content

Commit 5022f2e

Browse files
authored
feat: MemberControllerTest 추가, result 메시지 일관화 (#54)
1 parent 30ef87e commit 5022f2e

File tree

7 files changed

+138
-19
lines changed

7 files changed

+138
-19
lines changed

backend/src/main/java/com/back/domain/member/controller/ApiV1MemberController.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public ResponseEntity<ApiResponse<MemberDto>> signup(
3232
.status(HttpStatus.CREATED)
3333
.body(new ApiResponse<>(
3434
"201",
35-
"회원가입 성공",
35+
"[Member] Success: 회원 가입",
3636
new MemberDto(member)
3737
)
3838
);
@@ -53,7 +53,7 @@ public ResponseEntity<ApiResponse<LoginResDto>> login(
5353
.status(HttpStatus.OK)
5454
.body(new ApiResponse<>(
5555
"200",
56-
"로그인 성공",
56+
"[Member] Success: 로그인",
5757
new LoginResDto(
5858
new MemberDto(member),
5959
member.getApiKey(),
@@ -72,7 +72,7 @@ public ResponseEntity<ApiResponse<Void>> logout() {
7272
.status(HttpStatus.OK)
7373
.body(new ApiResponse<>(
7474
"200",
75-
"로그아웃 성공"
75+
"[Member] Success: 로그아웃"
7676
)
7777
);
7878
}
@@ -88,7 +88,7 @@ public ResponseEntity<ApiResponse<Boolean>> valid_check() {
8888
.status(HttpStatus.OK)
8989
.body(new ApiResponse<>(
9090
"200",
91-
"가입 완료 검사",
91+
"[Member] Success: 가입 완료 검사",
9292
valid
9393
)
9494
);
@@ -108,7 +108,7 @@ public ResponseEntity<ApiResponse<MemberDto>> valid_set(
108108
.status(HttpStatus.OK)
109109
.body(new ApiResponse<>(
110110
"200",
111-
"가입 완료 처리",
111+
"[Member] Success: 가입 완료 처리",
112112
new MemberDto(actor)
113113
)
114114
);
@@ -126,7 +126,7 @@ public ResponseEntity<ApiResponse<MemberDto>> modifyName(
126126
.status(HttpStatus.OK)
127127
.body(new ApiResponse<>(
128128
"200",
129-
"회원 닉네임 변경 성공",
129+
"[Member] Success: 닉네임 변경",
130130
new MemberDto(actor)
131131
)
132132
);
@@ -144,7 +144,7 @@ public ResponseEntity<ApiResponse<MemberDto>> modifyProfile(
144144
.status(HttpStatus.OK)
145145
.body(new ApiResponse<>(
146146
"200",
147-
"회원 정보 수정 성공",
147+
"[Member] Success: 정보 수정",
148148
new MemberDto(actor)
149149
)
150150
);
@@ -163,7 +163,7 @@ public ResponseEntity<ApiResponse<MemberDto>> modifyPassword(
163163
.status(HttpStatus.OK)
164164
.body(new ApiResponse<>(
165165
"200",
166-
"회원 비밀번호 변경 성공"
166+
"[Member] Success: 비밀번호 변경"
167167
)
168168
);
169169
}
@@ -177,7 +177,7 @@ public ResponseEntity<ApiResponse<MemberDto>> me() {
177177
.status(HttpStatus.OK)
178178
.body(new ApiResponse<>(
179179
"200",
180-
"로그인된 사용자: %s".formatted(actor.getEmail()),
180+
"[Member] Success: 사용자 정보 확인 (%s)".formatted(actor.getEmail()),
181181
new MemberDto(actor)
182182
)
183183
);
@@ -196,7 +196,7 @@ public ResponseEntity<ApiResponse<Void>> delete() {
196196
.status(HttpStatus.OK)
197197
.body(new ApiResponse<>(
198198
"200",
199-
"회원 탈퇴 완료"
199+
"[Member] Success: 회원 탈퇴"
200200
)
201201
);
202202
}

backend/src/main/java/com/back/domain/member/service/MemberService.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public Member signup(
3131
) {
3232
findByEmail(email)
3333
.ifPresent(_member -> {
34-
throw new CustomException(ErrorCode.CONFLICT, "이미 가입된 계정입니다.");
34+
throw new CustomException(ErrorCode.CONFLICT, "[Member] Fail: 이미 가입된 계정");
3535
});
3636

3737
password = passwordEncoder.encode(password);
@@ -55,9 +55,9 @@ public Member social_signup(String email, String password, String name) {
5555
//로그인 (일반)
5656
public Member login(String email, String password) {
5757
Member member = findByEmail(email)
58-
.orElseThrow(() -> new CustomException(ErrorCode.UNAUTHORIZED, "잘못된 이메일입니다."));
58+
.orElseThrow(() -> new CustomException(ErrorCode.UNAUTHORIZED, "[Member] Fail: 잘못된 이메일"));
5959
if(!passwordEncoder.matches(password, member.getPassword())) {
60-
throw new CustomException(ErrorCode.UNAUTHORIZED, "잘못된 비밀번호입니다.");
60+
throw new CustomException(ErrorCode.UNAUTHORIZED, "[Member] Fail: 잘못된 비밀번호");
6161
}
6262

6363
return member;

backend/src/main/java/com/back/global/initData/BaseInitData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public void initAllData() {
3636
createMember();
3737
createItem();
3838
} catch (Exception e) {
39-
throw new RuntimeException("initData 생성 실패", e);
39+
throw new RuntimeException("[initData] Fail: 초기 데이터 생성 실패", e);
4040
}
4141
}
4242

backend/src/main/java/com/back/global/rq/Rq.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ public Member getActor() {
3434
.filter(principal -> principal instanceof SecurityUser)
3535
.map(principal -> (SecurityUser) principal)
3636
.map(securityUser -> new Member(securityUser.getId(), securityUser.getUsername()))
37-
.orElseThrow(() -> new CustomException(ErrorCode.UNAUTHORIZED, "로그인된 사용자를 찾을 수 없습니다."));
37+
.orElseThrow(() -> new CustomException(ErrorCode.UNAUTHORIZED, "[Rq] Fail: 로그인된 사용자를 찾을 수 없음"));
3838
}
3939

4040
public Member getActorFromDb() {
4141
Member actor = getActor();
4242

4343
return memberService.findById(actor.getId())
44-
.orElseThrow(() -> new CustomException(ErrorCode.UNAUTHORIZED, "로그인된 사용자를 찾을 수 없습니다."));
44+
.orElseThrow(() -> new CustomException(ErrorCode.UNAUTHORIZED, "[Rq] Fail: 로그인된 사용자를 찾을 수 없음"));
4545
}
4646

4747
public String getHeader(String name, String defaultValue) {

backend/src/main/java/com/back/global/security/CustomAuthenticationFilter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ private void work(HttpServletRequest request, HttpServletResponse response, Filt
5959

6060
if (!headerAuthorization.isBlank()) {
6161
if (!headerAuthorization.startsWith("Bearer "))
62-
throw new CustomException(ErrorCode.UNAUTHORIZED, "Authorization 헤더가 Bearer 형식이 아닙니다.");
62+
throw new CustomException(ErrorCode.UNAUTHORIZED, "[Security] Fail: Authorization 헤더가 Bearer 형식이 아님");
6363

6464
String[] headerAuthorizationBits = headerAuthorization.split(" ", 3);
6565

@@ -99,7 +99,7 @@ private void work(HttpServletRequest request, HttpServletResponse response, Filt
9999
if (member == null) {
100100
member = memberService
101101
.findByApiKey(apiKey)
102-
.orElseThrow(() -> new CustomException(ErrorCode.UNAUTHORIZED, "API 키가 유효하지 않습니다."));
102+
.orElseThrow(() -> new CustomException(ErrorCode.UNAUTHORIZED, "[Security] Fail: API 유효하지 않음"));
103103
}
104104

105105
if (isAccessTokenExists && !isAccessTokenValid) {

backend/src/main/java/com/back/global/security/CustomUserDetailsService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class CustomUserDetailsService implements UserDetailsService {
1717
@Override
1818
public UserDetails loadUserByUsername(String username) throws CustomException {
1919
Member member = memberService.findByEmail(username)
20-
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND, "사용자를 찾을 수 없습니다."));
20+
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND, "[Security] Fail: 사용자를 찾을 수 없음"));
2121

2222
return new SecurityUser(
2323
member.getId(),
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package com.back.domain.member;
2+
3+
import com.back.domain.member.controller.ApiV1MemberController;
4+
import com.back.domain.member.entity.Member;
5+
import com.back.domain.member.service.MemberService;
6+
import jakarta.servlet.http.Cookie;
7+
import org.junit.jupiter.api.BeforeEach;
8+
import org.junit.jupiter.api.DisplayName;
9+
import org.junit.jupiter.api.Test;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
12+
import org.springframework.boot.test.context.SpringBootTest;
13+
import org.springframework.http.MediaType;
14+
import org.springframework.test.context.ActiveProfiles;
15+
import org.springframework.test.web.servlet.MockMvc;
16+
import org.springframework.test.web.servlet.ResultActions;
17+
import org.springframework.transaction.annotation.Transactional;
18+
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
21+
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
22+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
23+
24+
@ActiveProfiles("test")
25+
@SpringBootTest
26+
@AutoConfigureMockMvc
27+
@Transactional
28+
@DisplayName("회원 API 테스트")
29+
public class ApiV1MemberControllerTest {
30+
private final String baseUrl = "/api/v1/members";
31+
32+
@Autowired
33+
private MemberService memberService;
34+
@Autowired
35+
private MockMvc mvc;
36+
37+
private Member user1;
38+
39+
@BeforeEach
40+
void setUp() {
41+
user1 = memberService.signup(
42+
43+
"test123",
44+
"테스트유저1"
45+
);
46+
}
47+
48+
@Test
49+
@DisplayName("회원 가입")
50+
void signup() throws Exception {
51+
ResultActions resultActions = mvc
52+
.perform(
53+
post(baseUrl + "/signup")
54+
.contentType(MediaType.APPLICATION_JSON)
55+
.content("""
56+
{
57+
"email": "[email protected]",
58+
"password": "123",
59+
"name": "가입테스트"
60+
}
61+
""".stripIndent())
62+
)
63+
.andDo(print());
64+
65+
Member member = memberService.findByEmail("[email protected]").get();
66+
67+
resultActions
68+
.andExpect(handler().handlerType(ApiV1MemberController.class))
69+
.andExpect(handler().methodName("signup"))
70+
.andExpect(status().isCreated())
71+
.andExpect(jsonPath("$.code").value("201"))
72+
.andExpect(jsonPath("$.message").value("[Member] Success: 회원 가입"))
73+
.andExpect(jsonPath("$.content").exists())
74+
.andExpect(jsonPath("$.content.name").value(member.getName()));
75+
}
76+
77+
@Test
78+
@DisplayName("로그인")
79+
void login() throws Exception {
80+
ResultActions resultActions = mvc
81+
.perform(
82+
post(baseUrl + "/login")
83+
.contentType(MediaType.APPLICATION_JSON)
84+
.content("""
85+
{
86+
"email": "[email protected]",
87+
"password": "test123"
88+
}
89+
""".stripIndent())
90+
)
91+
.andDo(print());
92+
93+
resultActions
94+
.andExpect(handler().handlerType(ApiV1MemberController.class))
95+
.andExpect(handler().methodName("login"))
96+
.andExpect(status().isOk())
97+
.andExpect(jsonPath("$.code").value("200"))
98+
.andExpect(jsonPath("$.message").value("[Member] Success: 로그인"))
99+
.andExpect(jsonPath("$.content").exists())
100+
.andExpect(jsonPath("$.content.item").exists())
101+
.andExpect(jsonPath("$.content.item.name").value(user1.getName()))
102+
.andExpect(jsonPath("$.content.apiKey").value(user1.getApiKey()))
103+
.andExpect(jsonPath("$.content.accessToken").isNotEmpty());
104+
105+
resultActions.andExpect(
106+
result -> {
107+
Cookie apiKeyCookie = result.getResponse().getCookie("apiKey");
108+
assertThat(apiKeyCookie.getValue()).isEqualTo(user1.getApiKey());
109+
assertThat(apiKeyCookie.getPath()).isEqualTo("/");
110+
assertThat(apiKeyCookie.getAttribute("HttpOnly")).isEqualTo("true");
111+
112+
Cookie accessTokenCookie = result.getResponse().getCookie("accessToken");
113+
assertThat(accessTokenCookie.getValue()).isNotBlank();
114+
assertThat(accessTokenCookie.getPath()).isEqualTo("/");
115+
assertThat(accessTokenCookie.getAttribute("HttpOnly")).isEqualTo("true");
116+
}
117+
);
118+
}
119+
}

0 commit comments

Comments
 (0)