44import com .backend .domain .member .dto .MemberModifyRequestDto ;
55import com .backend .domain .member .dto .MemberSignUpRequestDto ;
66import com .backend .domain .member .repository .MemberRepository ;
7+ import com .backend .domain .product .service .FileService ;
78import com .backend .global .redis .TestRedisConfiguration ;
89import com .fasterxml .jackson .databind .ObjectMapper ;
10+ import com .jayway .jsonpath .JsonPath ;
11+ import org .springframework .boot .test .mock .mockito .MockBean ;
12+ import static org .mockito .ArgumentMatchers .any ;
13+ import static org .mockito .BDDMockito .given ;
914import org .springframework .boot .autoconfigure .EnableAutoConfiguration ;
1015import org .springframework .context .annotation .Import ;
1116import org .junit .jupiter .api .AfterEach ;
3035import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .get ;
3136import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .post ;
3237import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .put ;
38+ import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .delete ;
3339import static org .springframework .test .web .servlet .result .MockMvcResultHandlers .print ;
3440import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .*;
3541
@@ -56,6 +62,9 @@ class ApiV1MemberControllerTest {
5662 @ Autowired
5763 private RedisTemplate <String , Object > redisTemplate ;
5864
65+ @ MockBean
66+ private FileService fileService ;
67+
5968 @ BeforeEach
6069 void setUp () {
6170 // 각 테스트 실행 전에 데이터 정리
@@ -373,7 +382,9 @@ void t10() throws Exception {
373382 @ Test
374383 @ DisplayName ("내 정보 수정 성공" )
375384 void t11 () throws Exception {
376- // Given
385+ // given
386+ given (fileService .uploadFile (any (), any ())).willReturn ("https://test.com/modified.jpg" );
387+
377388 // 회원가입
378389 MemberSignUpRequestDto signUpDto = new MemberSignUpRequestDto (
379390 "[email protected] " ,
"password123" ,
"beforeModify" ,
"01011112222" ,
"Before Address" );
@@ -423,7 +434,7 @@ void t11() throws Exception {
423434 .andExpect (jsonPath ("$.data.nickname" ).value ("afterModify" ))
424435 .andExpect (jsonPath ("$.data.phoneNumber" ).value ("01099998888" ))
425436 .andExpect (jsonPath ("$.data.address" ).value ("After Address" ))
426- .andExpect (jsonPath ("$.data.profileImageUrl" ).exists ( ));
437+ .andExpect (jsonPath ("$.data.profileImageUrl" ).value ( "https://test.com/modified.jpg" ));
427438 }
428439
429440 @ Test
@@ -449,4 +460,95 @@ void t12() throws Exception {
449460 .andExpect (jsonPath ("$.data.id" ).value (memberId ))
450461 .andExpect (jsonPath ("$.data.nickname" ).value ("testUser12" ));
451462 }
463+
464+ @ Test
465+ @ DisplayName ("회원탈퇴 성공" )
466+ void t13 () throws Exception {
467+ // given
468+ // 회원가입
469+ MemberSignUpRequestDto signUpDto = new MemberSignUpRequestDto (
470+ "[email protected] " ,
"password123" ,
"withdrawUser" ,
"01033334444" ,
"Withdraw Address" );
471+ mockMvc .perform (post ("/api/v1/auth/signup" )
472+ .contentType (MediaType .APPLICATION_JSON )
473+ .content (objectMapper .writeValueAsString (signUpDto )));
474+
475+ // 로그인하여 토큰 발급
476+ LoginRequestDto loginDto =
new LoginRequestDto (
"[email protected] " ,
"password123" );
477+ ResultActions loginResult = mockMvc .perform (post ("/api/v1/auth/login" )
478+ .contentType (MediaType .APPLICATION_JSON )
479+ .content (objectMapper .writeValueAsString (loginDto )));
480+ String responseBody = loginResult .andReturn ().getResponse ().getContentAsString ();
481+ String accessToken = objectMapper .readTree (responseBody ).get ("data" ).get ("accessToken" ).asText ();
482+
483+ // when
484+ // 회원탈퇴
485+ ResultActions withdrawResult = mockMvc .perform (delete ("/api/v1/members/me" )
486+ .header ("Authorization" , "Bearer " + accessToken ))
487+ .andDo (print ());
488+
489+ // then
490+ withdrawResult
491+ .andExpect (status ().isOk ())
492+ .andExpect (jsonPath ("$.resultCode" ).value ("200-5" ))
493+ .andExpect (jsonPath ("$.msg" ).value ("회원 탈퇴가 완료되었습니다." ));
494+
495+ // given
496+ // 탈퇴한 계정으로 다시 로그인 시도
497+ LoginRequestDto reloginDto =
new LoginRequestDto (
"[email protected] " ,
"password123" );
498+
499+ // when
500+ ResultActions reloginResult = mockMvc .perform (post ("/api/v1/auth/login" )
501+ .contentType (MediaType .APPLICATION_JSON )
502+ .content (objectMapper .writeValueAsString (reloginDto )))
503+ .andDo (print ());
504+
505+ // then
506+ // 존재하지 않는 이메일이므로 404 Not Found 응답을 기대
507+ reloginResult .andExpect (status ().isNotFound ());
508+ }
509+
510+ @ Test
511+ @ DisplayName ("내 정보 수정 성공 - 프로필 이미지 제외" )
512+ void t14 () throws Exception {
513+ // given: FileService가 항상 짧은 URL을 반환하도록 Mocking
514+ given (fileService .uploadFile (any (), any ())).willReturn ("https://test.com/initial.jpg" );
515+
516+ // 1. 초기 이미지와 함께 회원가입 및 정보 수정
517+ MemberSignUpRequestDto signUpDto = new MemberSignUpRequestDto (
518+ "[email protected] " ,
"password123" ,
"imageUser" ,
"01055556666" ,
"Image Address" );
519+ mockMvc .perform (post ("/api/v1/auth/signup" )
520+ .contentType (MediaType .APPLICATION_JSON )
521+ .content (objectMapper .writeValueAsString (signUpDto )));
522+
523+ LoginRequestDto loginDto =
new LoginRequestDto (
"[email protected] " ,
"password123" );
524+ ResultActions loginResult = mockMvc .perform (post ("/api/v1/auth/login" )
525+ .contentType (MediaType .APPLICATION_JSON )
526+ .content (objectMapper .writeValueAsString (loginDto )));
527+ String accessToken = JsonPath .read (loginResult .andReturn ().getResponse ().getContentAsString (), "$.data.accessToken" );
528+
529+ MockMultipartFile initialImage = new MockMultipartFile ("profileImage" , "initial.jpg" , MediaType .IMAGE_JPEG_VALUE , "initial image" .getBytes ());
530+ MemberModifyRequestDto initialModifyDto = new MemberModifyRequestDto ("imageUser" , "01055556666" , "Image Address" );
531+ MockMultipartFile initialModifyDtoPart = new MockMultipartFile ("memberModifyRequestDto" , "" , "application/json" , objectMapper .writeValueAsString (initialModifyDto ).getBytes (StandardCharsets .UTF_8 ));
532+
533+ mockMvc .perform (multipart (HttpMethod .PUT , "/api/v1/members/me" )
534+ .file (initialImage )
535+ .file (initialModifyDtoPart )
536+ .header ("Authorization" , "Bearer " + accessToken ));
537+
538+ // 2. 이미지를 제외하고 다른 정보만 수정
539+ MemberModifyRequestDto secondModifyDto = new MemberModifyRequestDto ("newNickname" , "01077778888" , "New Address" );
540+ MockMultipartFile secondModifyDtoPart = new MockMultipartFile ("memberModifyRequestDto" , "" , "application/json" , objectMapper .writeValueAsString (secondModifyDto ).getBytes (StandardCharsets .UTF_8 ));
541+
542+ ResultActions secondModifyResult = mockMvc .perform (multipart (HttpMethod .PUT , "/api/v1/members/me" )
543+ .file (secondModifyDtoPart ) // 이미지를 보내지 않음
544+ .header ("Authorization" , "Bearer " + accessToken ))
545+ .andDo (print ());
546+
547+ // 3. 닉네임은 변경되고, 이미지 URL은 1차 수정 때의 값("https://test.com/initial.jpg")이 그대로 유지되는지 확인
548+ secondModifyResult
549+ .andExpect (status ().isOk ())
550+ .andExpect (jsonPath ("$.resultCode" ).value ("200-4" ))
551+ .andExpect (jsonPath ("$.data.nickname" ).value ("newNickname" ))
552+ .andExpect (jsonPath ("$.data.profileImageUrl" ).value ("https://test.com/initial.jpg" ));
553+ }
452554}
0 commit comments