33import com .back .domain .post .dto .PostRequest ;
44import com .back .domain .post .entity .Post ;
55import com .back .domain .post .enums .PostCategory ;
6+ import com .back .domain .post .enums .SearchType ;
7+ import com .back .domain .post .fixture .PostFixture ;
68import com .back .domain .post .repository .PostRepository ;
7- import com .back .domain .user .entity .Gender ;
8- import com .back .domain .user .entity .Mbti ;
9- import com .back .domain .user .entity .Role ;
109import com .back .domain .user .entity .User ;
1110import com .back .domain .user .repository .UserRepository ;
1211import com .back .global .exception .ErrorCode ;
1312import com .fasterxml .jackson .databind .ObjectMapper ;
13+ import org .hamcrest .Matchers ;
1414import org .junit .jupiter .api .BeforeEach ;
1515import org .junit .jupiter .api .DisplayName ;
1616import org .junit .jupiter .api .Nested ;
2525import org .springframework .test .web .servlet .MockMvc ;
2626import org .springframework .transaction .annotation .Transactional ;
2727
28- import java .time .LocalDateTime ;
29- import java .util .stream .IntStream ;
30-
3128import static org .springframework .test .web .servlet .request .MockMvcRequestBuilders .*;
29+ import static org .springframework .test .web .servlet .result .MockMvcResultHandlers .print ;
3230import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .jsonPath ;
3331import static org .springframework .test .web .servlet .result .MockMvcResultMatchers .status ;
3432
@@ -50,45 +48,16 @@ class PostControllerTest {
5048 @ Autowired
5149 private UserRepository userRepository ;
5250
51+ private PostFixture fixture ;
5352 private User testUser ;
5453 private User anotherUser ;
5554
5655 @ BeforeEach
5756 void setUp () {
58- testUser = User .builder ()
59- .loginId ("testLoginId" )
60- 61- .password ("testPassword" )
62- .beliefs ("도전" )
63- .gender (Gender .M )
64- .role (Role .USER )
65- .mbti (Mbti .ISFJ )
66- .birthdayAt (LocalDateTime .of (2000 , 3 , 1 , 0 , 0 ))
67- .build ();
68- userRepository .save (testUser );
69-
70- anotherUser = User .builder ()
71- .loginId ("anotherLoginId" )
72- 73- .password ("another" )
74- .beliefs ("도전" )
75- .gender (Gender .F )
76- .role (Role .USER )
77- .mbti (Mbti .ISFJ )
78- .birthdayAt (LocalDateTime .of (2001 , 4 , 1 , 0 , 0 ))
79- .build ();
80- userRepository .save (anotherUser );
81-
82- IntStream .rangeClosed (1 , 5 ).forEach (i -> {
83- postRepository .save (
84- Post .builder ()
85- .title ("목록 게시글 " + i )
86- .content ("목록 내용 " + i )
87- .category (PostCategory .CHAT )
88- .user (testUser )
89- .build ()
90- );
91- });
57+ fixture = new PostFixture (userRepository , postRepository );
58+ testUser = fixture .createTestUser ();
59+ anotherUser = fixture .createAnotherUser ();
60+ fixture .createPostsForPaging (testUser , 5 );
9261 }
9362
9463 @ Nested
@@ -99,10 +68,10 @@ class CreatePost {
9968 @ DisplayName ("성공 - 정상 요청" )
10069 void success () throws Exception {
10170 // given
102- PostRequest request = new PostRequest ( "테스트 게시글" , "테스트 내용입니다." , PostCategory . CHAT );
71+ PostRequest request = fixture . createPostRequest ( );
10372
104- // when
105- mockMvc .perform (post ("/api/v1/posts" )
73+ // when & then
74+ mockMvc .perform (post (PostFixture . API_BASE_PATH )
10675 .contentType (MediaType .APPLICATION_JSON )
10776 .content (objectMapper .writeValueAsString (request )))
10877 .andExpect (status ().isOk ())
@@ -114,19 +83,33 @@ void success() throws Exception {
11483 }
11584
11685 @ Test
117- @ DisplayName ("실패 - 유효성 검사 실패" )
118- void fail_ValidationError () throws Exception {
86+ @ DisplayName ("실패 - 유효성 검사 실패 (빈 제목) " )
87+ void fail_ValidationError_EmptyTitle () throws Exception {
11988 // given
120- PostRequest request = new PostRequest ( "" , "테스트 내용입니다." , PostCategory . CHAT );
89+ PostRequest request = fixture . createEmptyTitleRequest ( );
12190
12291 // when & then
123- mockMvc .perform (post ("/api/v1/posts" )
92+ mockMvc .perform (post (PostFixture . API_BASE_PATH )
12493 .contentType (MediaType .APPLICATION_JSON )
12594 .content (objectMapper .writeValueAsString (request )))
12695 .andExpect (status ().isBadRequest ())
12796 .andExpect (jsonPath ("$.code" ).value (ErrorCode .INVALID_INPUT_VALUE .getCode ()))
12897 .andExpect (jsonPath ("$.message" ).exists ());
12998 }
99+
100+ @ Test
101+ @ DisplayName ("실패 - 유효성 검사 실패 (빈 내용)" )
102+ void fail_ValidationError_EmptyContent () throws Exception {
103+ // given
104+ PostRequest request = fixture .createEmptyContentRequest ();
105+
106+ // when & then
107+ mockMvc .perform (post (PostFixture .API_BASE_PATH )
108+ .contentType (MediaType .APPLICATION_JSON )
109+ .content (objectMapper .writeValueAsString (request )))
110+ .andExpect (status ().isBadRequest ())
111+ .andExpect (jsonPath ("$.code" ).value (ErrorCode .INVALID_INPUT_VALUE .getCode ()));
112+ }
130113 }
131114
132115 @ Nested
@@ -137,17 +120,10 @@ class GetPost {
137120 @ DisplayName ("성공 - 존재하는 게시글 조회" )
138121 void success () throws Exception {
139122 // given
140- Post savedPost = postRepository .save (
141- Post .builder ()
142- .title ("조회 테스트 게시글" )
143- .content ("조회 테스트 내용입니다." )
144- .category (PostCategory .CHAT )
145- .user (userRepository .findAll ().get (0 ))
146- .build ()
147- );
123+ Post savedPost = fixture .createPostForDetail (testUser );
148124
149125 // when & then
150- mockMvc .perform (get ("/api/v1/posts /{postId}" , savedPost .getId ()))
126+ mockMvc .perform (get (PostFixture . API_BASE_PATH + " /{postId}" , savedPost .getId ()))
151127 .andExpect (status ().isOk ())
152128 .andExpect (jsonPath ("$.data.title" ).value ("조회 테스트 게시글" ))
153129 .andExpect (jsonPath ("$.data.content" ).value ("조회 테스트 내용입니다." ))
@@ -160,12 +136,12 @@ void success() throws Exception {
160136 @ DisplayName ("실패 - 존재하지 않는 게시글 ID" )
161137 void fail_NotFound () throws Exception {
162138 // when & then
163- mockMvc .perform (get ("/api/v1/posts/ {postId}" , 9999L ))
139+ mockMvc .perform (get (PostFixture . API_BASE_PATH + "/ {postId}" , PostFixture . NON_EXISTENT_POST_ID ))
164140 .andExpect (status ().isNotFound ())
165141 .andExpect (jsonPath ("$.status" ).value (HttpStatus .NOT_FOUND .value ()))
166142 .andExpect (jsonPath ("$.code" ).value (ErrorCode .POST_NOT_FOUND .getCode ()))
167143 .andExpect (jsonPath ("$.message" ).value (ErrorCode .POST_NOT_FOUND .getMessage ()))
168- .andExpect (jsonPath ("$.path" ).value ("/api/v1/posts/9999" ));
144+ .andExpect (jsonPath ("$.path" ).value (PostFixture . API_BASE_PATH + "/" + PostFixture . NON_EXISTENT_POST_ID ));
169145 }
170146 }
171147
@@ -177,7 +153,7 @@ class GetPosts {
177153 @ DisplayName ("성공 - 페이징 파라미터가 없는 경우" )
178154 void successWithDefaultParameters () throws Exception {
179155 // when & then
180- mockMvc .perform (get ("/api/v1/posts" ))
156+ mockMvc .perform (get (PostFixture . API_BASE_PATH ))
181157 .andExpect (status ().isOk ())
182158 .andExpect (jsonPath ("$.data.page" ).value (1 ))
183159 .andExpect (jsonPath ("$.data.size" ).value (5 ))
@@ -189,35 +165,58 @@ void successWithDefaultParameters() throws Exception {
189165 @ DisplayName ("성공 - page와 size 모두 지정" )
190166 void successWithBothParameters () throws Exception {
191167 // when & then
192- mockMvc .perform (get ("/api/v1/posts" )
168+ mockMvc .perform (get (PostFixture . API_BASE_PATH )
193169 .param ("page" , "1" )
194170 .param ("size" , "5" ))
195171 .andExpect (status ().isOk ())
196172 .andExpect (jsonPath ("$.data.items.length()" ).value (5 ))
197- .andExpect (jsonPath ("$.data.items[0].title" ).value ("목록 게시글 1" ))
198- .andExpect (jsonPath ("$.data.items[1].title" ).value ("목록 게시글 2" ))
173+ .andExpect (jsonPath ("$.data.items[0].title" ).value ("시나리오 게시글 2" ))
174+ .andExpect (jsonPath ("$.data.items[1].title" ).value ("시나리오 게시글 1" ))
175+ .andExpect (jsonPath ("$.data.items[2].title" ).value ("목록 게시글 5" ))
199176 .andExpect (jsonPath ("$.data.page" ).value (1 ))
200177 .andExpect (jsonPath ("$.data.size" ).value (5 ))
201- .andExpect (jsonPath ("$.data.totalElements" ).value (5 ))
202- .andExpect (jsonPath ("$.data.totalPages" ).value (1 ))
203- .andExpect (jsonPath ("$.data.last" ).value (true ))
204- .andExpect (jsonPath ("$.status" ).value (200 ))
205- .andExpect (jsonPath ("$.message" ).value ("성공적으로 조회되었습니다." ));
178+ .andExpect (jsonPath ("$.data.totalElements" ).value (7 ))
179+ .andExpect (jsonPath ("$.data.totalPages" ).value (2 ))
180+ .andExpect (jsonPath ("$.data.last" ).value (false ));
206181 }
207182
208183 @ Test
209- @ DisplayName ("성공 - 정렬 파라미터 포함 " )
210- void successWithSortParameters () throws Exception {
184+ @ DisplayName ("성공 - 카테고리 필터링 적용 " )
185+ void successWithCategoryFilter () throws Exception {
211186 // when & then
212- mockMvc .perform (get ("/api/v1/posts" )
213- .param ("page" , "1" )
214- .param ("size" , "5" )
215- .param ("sort" , "createdDate,desc" )
216- .param ("sort" , "title,asc" ))
187+ mockMvc .perform (get (PostFixture .API_BASE_PATH )
188+ .param ("category" , PostCategory .SCENARIO .name ()))
217189 .andExpect (status ().isOk ())
218- .andExpect (jsonPath ("$.data.page" ).value (1 ))
219- .andExpect (jsonPath ("$.data.size" ).value (5 ))
220- .andExpect (jsonPath ("$.status" ).value (200 ));
190+ .andExpect (jsonPath ("$.data.items[*].category" ).value (
191+ Matchers .everyItem (Matchers .equalTo ("SCENARIO" ))
192+ ))
193+ .andExpect (jsonPath ("$.data.items.length()" ).value (2 ))
194+ .andDo (print ());
195+ }
196+
197+ @ Test
198+ @ DisplayName ("성공 - 제목 + 내용 검색" )
199+ void successWithTitleContentSearch () throws Exception {
200+ // when & then
201+ mockMvc .perform (get (PostFixture .API_BASE_PATH )
202+ .param ("searchType" , SearchType .TITLE_CONTENT .name ())
203+ .param ("keyword" , "시나리오" ))
204+ .andExpect (status ().isOk ())
205+ .andExpect (jsonPath ("$.data.items.length()" ).value (2 ))
206+ .andDo (print ());
207+ }
208+
209+ @ Test
210+ @ DisplayName ("성공 - 작성자 검색" )
211+ void successWithAuthorSearch () throws Exception {
212+ // when & then
213+ mockMvc .perform (get (PostFixture .API_BASE_PATH )
214+ .param ("searchType" , SearchType .AUTHOR .name ())
215+ .param ("keyword" , "작성자1" ))
216+ .andExpect (status ().isOk ())
217+ .andExpect (jsonPath ("$.data.items[*].author" ,
218+ Matchers .everyItem (Matchers .containsStringIgnoringCase ("작성자1" ))))
219+ .andDo (print ());
221220 }
222221 }
223222
@@ -231,21 +230,13 @@ class UpdatePost {
231230 "UPDATE users SET id = 1 WHERE login_id = 'testLoginId'"
232231 })
233232 void success () throws Exception {
234- // given - ID=1인 사용자의 게시글 생성
233+ // given
235234 User user1 = userRepository .findById (1L ).orElseThrow ();
236- Post savedPost = postRepository .save (
237- Post .builder ()
238- .title ("수정 전 제목" )
239- .content ("수정 전 내용" )
240- .category (PostCategory .CHAT )
241- .user (user1 )
242- .build ()
243- );
244-
245- PostRequest updateRequest = new PostRequest ("수정된 제목" , "수정된 내용" , PostCategory .CHAT );
235+ Post savedPost = fixture .createPostForUpdate (user1 );
236+ PostRequest updateRequest = fixture .createUpdateRequest ();
246237
247238 // when & then
248- mockMvc .perform (put ("/api/v1/posts /{postId}" , savedPost .getId ())
239+ mockMvc .perform (put (PostFixture . API_BASE_PATH + " /{postId}" , savedPost .getId ())
249240 .contentType (MediaType .APPLICATION_JSON )
250241 .content (objectMapper .writeValueAsString (updateRequest )))
251242 .andExpect (status ().isOk ())
@@ -261,21 +252,13 @@ void success() throws Exception {
261252 "UPDATE users SET id = 2 WHERE login_id = 'anotherLoginId'"
262253 })
263254 void fail_UnauthorizedUser () throws Exception {
264- // given - ID=2인 사용자의 게시글 (ID=1 사용자가 수정 시도)
255+ // given
265256 User user2 = userRepository .findById (2L ).orElseThrow ();
266- Post savedPost = postRepository .save (
267- Post .builder ()
268- .title ("다른 사용자 게시글" )
269- .content ("다른 사용자 내용" )
270- .category (PostCategory .CHAT )
271- .user (user2 )
272- .build ()
273- );
274-
275- PostRequest updateRequest = new PostRequest ("수정 시도" , "수정 시도 내용" , PostCategory .CHAT );
257+ Post savedPost = fixture .createPostForUpdate (user2 );
258+ PostRequest updateRequest = fixture .createUpdateRequest ();
276259
277260 // when & then
278- mockMvc .perform (put ("/api/v1/posts /{postId}" , savedPost .getId ())
261+ mockMvc .perform (put (PostFixture . API_BASE_PATH + " /{postId}" , savedPost .getId ())
279262 .contentType (MediaType .APPLICATION_JSON )
280263 .content (objectMapper .writeValueAsString (updateRequest )))
281264 .andExpect (status ().isUnauthorized ())
0 commit comments