1+ package com .back .domain .file .controller ;
2+
3+ import com .back .domain .board .post .entity .Post ;
4+ import com .back .domain .board .post .repository .PostRepository ;
5+ import com .back .domain .file .config .S3MockConfig ;
6+ import com .back .domain .user .entity .User ;
7+ import com .back .domain .user .entity .UserProfile ;
8+ import com .back .domain .user .entity .UserStatus ;
9+ import com .back .domain .user .repository .UserRepository ;
10+ import com .back .fixture .TestJwtTokenProvider ;
11+ import org .junit .jupiter .api .DisplayName ;
12+ import org .junit .jupiter .api .Test ;
13+ import org .springframework .beans .factory .annotation .Autowired ;
14+ import org .springframework .boot .test .autoconfigure .web .servlet .AutoConfigureMockMvc ;
15+ import org .springframework .boot .test .context .SpringBootTest ;
16+ import org .springframework .context .annotation .Import ;
17+ import org .springframework .mock .web .MockMultipartFile ;
18+ import org .springframework .security .crypto .password .PasswordEncoder ;
19+ import org .springframework .test .context .ActiveProfiles ;
20+ import org .springframework .test .web .servlet .MockMvc ;
21+ import org .springframework .test .web .servlet .ResultActions ;
22+ import org .springframework .transaction .annotation .Transactional ;
23+
24+ import java .time .LocalDate ;
25+
26+ import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .multipart ;
27+ import static org .springframework .test .web .servlet .result .MockMvcResultHandlers .print ;
28+ import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .jsonPath ;
29+ import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .status ;
30+
31+ @ SpringBootTest
32+ @ Import (S3MockConfig .class )
33+ @ ActiveProfiles ("test" )
34+ @ AutoConfigureMockMvc
35+ @ Transactional
36+ class FileControllerTest {
37+ @ Autowired
38+ private MockMvc mvc ;
39+
40+ @ Autowired
41+ private UserRepository userRepository ;
42+
43+ @ Autowired
44+ private PasswordEncoder passwordEncoder ;
45+
46+ @ Autowired
47+ private PostRepository postRepository ;
48+
49+ @ Autowired
50+ private TestJwtTokenProvider testJwtTokenProvider ;
51+
52+ private String generateAccessToken (User user ) {
53+ return testJwtTokenProvider .createAccessToken (
54+ user .getId (),
55+ user .getUsername (),
56+ user .getRole ().name ()
57+ );
58+ }
59+
60+ @ Test
61+ @ DisplayName ("파일 업로드 성공" )
62+ void uploadFile_success () throws Exception {
63+ // given
64+ User user =
User .
createUser (
"writer" ,
"[email protected] " ,
passwordEncoder .
encode (
"P@ssw0rd!" ));
65+ user .setUserProfile (new UserProfile (user , "홍길동" , null , "소개글" , LocalDate .of (2000 , 1 , 1 ), 1000 ));
66+ user .setUserStatus (UserStatus .ACTIVE );
67+ userRepository .save (user );
68+
69+ String accessToken = generateAccessToken (user );
70+
71+ Post post = new Post (user , "첫 글" , "내용" );
72+ postRepository .save (post );
73+
74+ MockMultipartFile multipartFile = new MockMultipartFile (
75+ "multipartFile" ,
76+ "test.png" ,
77+ "image/png" ,
78+ "test" .getBytes ()
79+ );
80+
81+ // when
82+ ResultActions resultActions = mvc .perform (
83+ multipart ("/api/file/upload" ) // 👈 post() 대신 multipart() 사용
84+ .file (multipartFile ) // 파일 필드
85+ .param ("entityType" , "POST" ) // DTO 필드 매핑
86+ .param ("entityId" , post .getId ().toString ())
87+ .header ("Authorization" , "Bearer " + accessToken )
88+ .characterEncoding ("UTF-8" )
89+ );
90+
91+ resultActions .andExpect (status ().isOk ())
92+ .andExpect (jsonPath ("$.code" ).value ("SUCCESS_200" ))
93+ .andExpect (jsonPath ("$.message" ).value ("파일 업로드 성공" ))
94+ .andDo (print ());
95+ }
96+
97+ @ Test
98+ @ DisplayName ("파일 업로드 실패 - 파일이 없는 경우" )
99+ void uploadFile_fail_noFile () throws Exception {
100+ // given
101+ User user =
User .
createUser (
"writer" ,
"[email protected] " ,
passwordEncoder .
encode (
"P@ssw0rd!" ));
102+ user .setUserProfile (new UserProfile (user , "홍길동" , null , "소개글" , LocalDate .of (2000 , 1 , 1 ), 1000 ));
103+ user .setUserStatus (UserStatus .ACTIVE );
104+ userRepository .save (user );
105+
106+ String accessToken = generateAccessToken (user );
107+
108+ Post post = new Post (user , "첫 글" , "내용" );
109+ postRepository .save (post );
110+
111+ // when
112+ ResultActions resultActions = mvc .perform (
113+ multipart ("/api/file/upload" ) // 👈 post() 대신 multipart() 사용
114+ .param ("entityType" , "POST" ) // DTO 필드 매핑
115+ .param ("entityId" , post .getId ().toString ())
116+ .header ("Authorization" , "Bearer " + accessToken )
117+ .characterEncoding ("UTF-8" )
118+ );
119+
120+ // then
121+ resultActions .andExpect (status ().isBadRequest ())
122+ .andExpect (jsonPath ("$.code" ).value ("COMMON_400" ))
123+ .andExpect (jsonPath ("$.message" ).value ("잘못된 요청입니다." ))
124+ .andDo (print ());
125+ }
126+ }
0 commit comments