1+ package com .back .domain .profile .controller ;
2+
3+ import com .back .domain .profile .dto .ProfileResponseDto ;
4+ import com .back .domain .profile .dto .ProfileUpdateRequestDto ;
5+ import com .back .domain .profile .service .ProfileService ;
6+ import com .back .domain .user .service .UserService ;
7+ import com .back .global .aspect .ResponseAspect ;
8+ import com .back .global .jwt .JwtUtil ;
9+ import com .back .global .rq .Rq ;
10+ import com .back .global .security .SecurityUser ;
11+ import org .junit .jupiter .api .AfterEach ;
12+ import org .junit .jupiter .api .DisplayName ;
13+ import org .junit .jupiter .api .Test ;
14+ import org .mockito .ArgumentCaptor ;
15+ import org .springframework .beans .factory .annotation .Autowired ;
16+ import org .springframework .boot .autoconfigure .ImportAutoConfiguration ;
17+ import org .springframework .boot .autoconfigure .aop .AopAutoConfiguration ;
18+ import org .springframework .boot .test .autoconfigure .web .servlet .AutoConfigureMockMvc ;
19+ import org .springframework .boot .test .autoconfigure .web .servlet .WebMvcTest ;
20+ import org .springframework .context .annotation .Import ;
21+ import org .springframework .http .MediaType ;
22+ import org .springframework .security .authentication .UsernamePasswordAuthenticationToken ;
23+ import org .springframework .security .core .authority .SimpleGrantedAuthority ;
24+ import org .springframework .security .core .context .SecurityContext ;
25+ import org .springframework .security .core .context .SecurityContextHolder ;
26+ import org .springframework .security .web .context .HttpSessionSecurityContextRepository ;
27+ import org .springframework .test .context .bean .override .mockito .MockitoBean ;
28+ import org .springframework .test .web .servlet .MockMvc ;
29+ import org .springframework .test .web .servlet .request .RequestPostProcessor ;
30+
31+ import java .util .List ;
32+ import java .util .Map ;
33+
34+ import static org .assertj .core .api .Assertions .assertThat ;
35+ import static org .mockito .ArgumentMatchers .any ;
36+ import static org .mockito .ArgumentMatchers .eq ;
37+ import static org .mockito .BDDMockito .given ;
38+ import static org .mockito .Mockito .verify ;
39+ import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .get ;
40+ import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .patch ;
41+ import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .jsonPath ;
42+ import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .status ;
43+
44+ @ WebMvcTest (ProfileController .class )
45+ @ AutoConfigureMockMvc (addFilters = false )
46+ @ Import (ResponseAspect .class )
47+ @ ImportAutoConfiguration (AopAutoConfiguration .class )
48+ class ProfileControllerTest {
49+
50+ @ Autowired
51+ private MockMvc mockMvc ;
52+
53+ @ MockitoBean
54+ private ProfileService profileService ;
55+
56+ @ MockitoBean
57+ private UserService userService ;
58+
59+ @ MockitoBean
60+ private JwtUtil jwtUtil ;
61+
62+ @ MockitoBean
63+ private Rq rq ;
64+
65+ @ AfterEach
66+ void clearSecurityContext () {
67+ SecurityContextHolder .clearContext ();
68+ }
69+
70+ private SecurityUser createPrincipal (Long userId ) {
71+ return new SecurityUser (
72+ userId ,
73+ "user" + userId + "@example.com" ,
74+ "user" + userId ,
75+ false ,
76+ List .of (new SimpleGrantedAuthority ("ROLE_USER" )),
77+ Map .of ()
78+ );
79+ }
80+
81+ private UsernamePasswordAuthenticationToken authenticated (SecurityUser principal ) {
82+ return new UsernamePasswordAuthenticationToken (principal , null , principal .getAuthorities ());
83+ }
84+
85+ private RequestPostProcessor withPrincipal (SecurityUser principal ) {
86+ return request -> {
87+ UsernamePasswordAuthenticationToken authentication = authenticated (principal );
88+ SecurityContext context = SecurityContextHolder .createEmptyContext ();
89+ context .setAuthentication (authentication );
90+ SecurityContextHolder .setContext (context );
91+ request .setUserPrincipal (authentication );
92+ request .getSession (true )
93+ .setAttribute (HttpSessionSecurityContextRepository .SPRING_SECURITY_CONTEXT_KEY , context );
94+ return request ;
95+ };
96+ }
97+
98+ @ Test
99+ @ DisplayName ("Get profile - success" )
100+ void getProfile_success () throws Exception {
101+ SecurityUser principal = createPrincipal (10L );
102+
103+ ProfileResponseDto responseDto = ProfileResponseDto .builder ()
104+ .id (principal .getId ())
105+ .nickname (principal .getNickname ())
106+ .email (principal .getEmail ())
107+ .abvDegree (12.5 )
108+ .abvLevel (2 )
109+ .abvLabel ("12.5%" )
110+ .myPostCount (7L )
111+ .myCommentCount (14L )
112+ .myLikedPostCount (5L )
113+ .build ();
114+
115+ given (profileService .getProfile (principal .getId ())).willReturn (responseDto );
116+
117+ mockMvc .perform (get ("/me/profile" )
118+ .with (withPrincipal (principal ))
119+ .accept (MediaType .APPLICATION_JSON ))
120+ .andExpect (status ().isOk ())
121+ .andExpect (jsonPath ("$.code" ).value (200 ))
122+ .andExpect (jsonPath ("$.message" ).value ("success" ))
123+ .andExpect (jsonPath ("$.data.id" ).value (principal .getId ()))
124+ .andExpect (jsonPath ("$.data.nickname" ).value (principal .getNickname ()))
125+ .andExpect (jsonPath ("$.data.email" ).value (principal .getEmail ()))
126+ .andExpect (jsonPath ("$.data.abvDegree" ).value (12.5 ))
127+ .andExpect (jsonPath ("$.data.abvLevel" ).value (2 ))
128+ .andExpect (jsonPath ("$.data.abvLabel" ).value ("12.5%" ))
129+ .andExpect (jsonPath ("$.data.myPostCount" ).value (7 ))
130+ .andExpect (jsonPath ("$.data.myCommentCount" ).value (14 ))
131+ .andExpect (jsonPath ("$.data.myLikedPostCount" ).value (5 ));
132+
133+ verify (profileService ).getProfile (principal .getId ());
134+ }
135+
136+ @ Test
137+ @ DisplayName ("Patch profile nickname - success" )
138+ void patchNickname_success () throws Exception {
139+ SecurityUser principal = createPrincipal (22L );
140+ String payload = "{\" nickname\" :\" newNick\" }" ;
141+
142+ ProfileResponseDto responseDto = ProfileResponseDto .builder ()
143+ .id (principal .getId ())
144+ .nickname ("newNick" )
145+ .email (principal .getEmail ())
146+ .abvDegree (20.0 )
147+ .abvLevel (3 )
148+ .abvLabel ("20.0%" )
149+ .myPostCount (11L )
150+ .myCommentCount (8L )
151+ .myLikedPostCount (3L )
152+ .build ();
153+
154+ given (profileService .updateProfile (eq (principal .getId ()), any (ProfileUpdateRequestDto .class )))
155+ .willReturn (responseDto );
156+
157+ mockMvc .perform (patch ("/me/profile" )
158+ .with (withPrincipal (principal ))
159+ .contentType (MediaType .APPLICATION_JSON )
160+ .content (payload )
161+ .accept (MediaType .APPLICATION_JSON ))
162+ .andExpect (status ().isOk ())
163+ .andExpect (jsonPath ("$.code" ).value (200 ))
164+ .andExpect (jsonPath ("$.message" ).value ("success" ))
165+ .andExpect (jsonPath ("$.data.nickname" ).value ("newNick" ));
166+
167+ ArgumentCaptor <ProfileUpdateRequestDto > captor = ArgumentCaptor .forClass (ProfileUpdateRequestDto .class );
168+ verify (profileService ).updateProfile (eq (principal .getId ()), captor .capture ());
169+ ProfileUpdateRequestDto captured = captor .getValue ();
170+ assertThat (captured .getNickname ()).isEqualTo ("newNick" );
171+ }
172+ }
0 commit comments