Skip to content

Commit eb3250d

Browse files
committed
test(review): 리뷰 수정 테스트
1 parent 117f544 commit eb3250d

File tree

3 files changed

+283
-10
lines changed

3 files changed

+283
-10
lines changed

src/test/java/com/somemore/domains/review/controller/ReviewCommandApiControllerTest.java

Lines changed: 124 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import com.fasterxml.jackson.core.JsonProcessingException;
44
import com.somemore.domains.review.dto.request.ReviewCreateRequestDto;
5+
import com.somemore.domains.review.dto.request.ReviewUpdateRequestDto;
56
import com.somemore.domains.review.usecase.CreateReviewUseCase;
67
import com.somemore.domains.review.usecase.DeleteReviewUseCase;
8+
import com.somemore.domains.review.usecase.UpdateReviewUseCase;
79
import com.somemore.global.imageupload.usecase.ImageUploadUseCase;
810
import com.somemore.support.ControllerTestSupport;
911
import com.somemore.support.annotation.WithMockCustomUser;
@@ -12,16 +14,17 @@
1214
import org.springframework.boot.test.mock.mockito.MockBean;
1315
import org.springframework.http.MediaType;
1416
import org.springframework.mock.web.MockMultipartFile;
17+
import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder;
1518

1619
import java.util.UUID;
1720

1821
import static org.mockito.ArgumentMatchers.any;
1922
import static org.mockito.ArgumentMatchers.anyString;
2023
import static org.mockito.BDDMockito.given;
2124
import static org.mockito.BDDMockito.willDoNothing;
25+
import static org.springframework.http.MediaType.APPLICATION_JSON;
2226
import static org.springframework.http.MediaType.MULTIPART_FORM_DATA;
23-
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
24-
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
27+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
2528
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
2629
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
2730

@@ -34,7 +37,10 @@ class ReviewCommandApiControllerTest extends ControllerTestSupport {
3437
private CreateReviewUseCase createReviewUseCase;
3538

3639
@MockBean
37-
DeleteReviewUseCase deleteReviewUseCase;
40+
private UpdateReviewUseCase updateReviewUseCase;
41+
42+
@MockBean
43+
private DeleteReviewUseCase deleteReviewUseCase;
3844

3945
@DisplayName("리뷰 생성 성공")
4046
@Test
@@ -154,6 +160,111 @@ void createReviewValidateTestContent() throws Exception {
154160
.andExpect(jsonPath("$.detail").value("리뷰 내용은 필수 값입니다."));
155161
}
156162

163+
@DisplayName("리뷰 수정 성공")
164+
@Test
165+
@WithMockCustomUser()
166+
void updateReview() throws Exception {
167+
// given
168+
ReviewUpdateRequestDto requestDto = ReviewUpdateRequestDto.builder()
169+
.title("리뷰 수정 제목")
170+
.content("리뷰 수정 내용")
171+
.build();
172+
173+
Long reviewId = 1L;
174+
175+
willDoNothing().given(updateReviewUseCase).updateReview(any(), any(UUID.class), any());
176+
String requestBody = objectMapper.writeValueAsString(requestDto);
177+
178+
// when
179+
mockMvc.perform(put("/api/review/{id}", reviewId)
180+
.content(requestBody)
181+
.contentType(APPLICATION_JSON)
182+
.header("Authorization", "Bearer access-token"))
183+
// then
184+
.andExpect(status().isOk())
185+
.andExpect(jsonPath("$.code").value(200))
186+
.andExpect(jsonPath("$.message").value("리뷰 수정 성공"));
187+
}
188+
189+
@DisplayName("리뷰 수정 유효성 테스트 - 제목")
190+
@Test
191+
@WithMockCustomUser()
192+
void updateReviewValidateTitle() throws Exception {
193+
// given
194+
ReviewUpdateRequestDto requestDto = ReviewUpdateRequestDto.builder()
195+
.content("업데이트 내용")
196+
.build();
197+
198+
Long reviewId = 1L;
199+
String requestBody = objectMapper.writeValueAsString(requestDto);
200+
201+
// when
202+
mockMvc.perform(put("/api/review/{id}", reviewId)
203+
.content(requestBody)
204+
.contentType(APPLICATION_JSON)
205+
.header("Authorization", "Bearer access-token"))
206+
// then
207+
.andExpect(status().isBadRequest())
208+
.andExpect(jsonPath("$.status").value(400))
209+
.andExpect(jsonPath("$.title").value("유효성 예외"))
210+
.andExpect(jsonPath("$.detail").value("리뷰 제목은 필수 값입니다."));
211+
}
212+
213+
@DisplayName("리뷰 수정 유효성 테스트 - 내용")
214+
@Test
215+
@WithMockCustomUser()
216+
void updateReviewValidateContent() throws Exception {
217+
// given
218+
ReviewUpdateRequestDto requestDto = ReviewUpdateRequestDto.builder()
219+
.title("업데이트 제목")
220+
.build();
221+
222+
Long reviewId = 1L;
223+
String requestBody = objectMapper.writeValueAsString(requestDto);
224+
225+
// when
226+
mockMvc.perform(put("/api/review/{id}", reviewId)
227+
.content(requestBody)
228+
.contentType(APPLICATION_JSON)
229+
.header("Authorization", "Bearer access-token"))
230+
// then
231+
.andExpect(status().isBadRequest())
232+
.andExpect(jsonPath("$.status").value(400))
233+
.andExpect(jsonPath("$.title").value("유효성 예외"))
234+
.andExpect(jsonPath("$.detail").value("리뷰 내용은 필수 값입니다."));
235+
}
236+
237+
@DisplayName("리뷰 이미지 수정 성공")
238+
@Test
239+
@WithMockCustomUser()
240+
void updateReviewImage() throws Exception {
241+
// given
242+
Long reviewId = 1L;
243+
244+
MockMultipartFile imageFile = new MockMultipartFile(
245+
"img_file",
246+
"test-image.jpg",
247+
MediaType.IMAGE_JPEG_VALUE,
248+
"test image content".getBytes()
249+
);
250+
251+
String imgUrl = "https://example.com/image/test-image.jpg";
252+
253+
given(imageUploadUseCase.uploadImage(any())).willReturn(imgUrl);
254+
255+
willDoNothing().given(updateReviewUseCase).updateReviewImageUrl(any(), any(UUID.class), anyString());
256+
257+
// when
258+
mockMvc.perform(createMultipartPutRequest("/api/review/{id}", reviewId)
259+
.file(imageFile)
260+
.contentType(MULTIPART_FORM_DATA)
261+
.header("Authorization", "Bearer access-token"))
262+
// then
263+
.andExpect(status().isOk())
264+
.andExpect(jsonPath("$.code").value(200))
265+
.andExpect(jsonPath("$.message").value("리뷰 이미지 수정 성공"));
266+
}
267+
157268
@DisplayName("리뷰 삭제 성공 테스트")
158269
@Test
159270
@WithMockCustomUser()
@@ -182,4 +293,14 @@ private MockMultipartFile getRequestData(ReviewCreateRequestDto requestDto)
182293
objectMapper.writeValueAsBytes(requestDto)
183294
);
184295
}
296+
297+
private MockMultipartHttpServletRequestBuilder createMultipartPutRequest(String url, Long id) {
298+
MockMultipartHttpServletRequestBuilder builder = multipart(url, id);
299+
builder.with(request -> {
300+
request.setMethod("PUT");
301+
return request;
302+
});
303+
return builder;
304+
}
305+
185306
}

src/test/java/com/somemore/domains/review/domain/ReviewTest.java

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.somemore.domains.review.domain;
22

3+
import com.somemore.domains.review.dto.request.ReviewUpdateRequestDto;
4+
import org.junit.jupiter.api.BeforeEach;
35
import org.junit.jupiter.api.DisplayName;
46
import org.junit.jupiter.api.Test;
57

@@ -10,15 +12,19 @@
1012

1113
class ReviewTest {
1214

15+
private UUID volunteerId;
16+
private Review review;
17+
18+
@BeforeEach
19+
void setUp() {
20+
volunteerId = UUID.randomUUID();
21+
review = createReview(1L, volunteerId);
22+
}
23+
1324
@DisplayName("작성자 인지 확인할 수 있다.")
1425
@Test
1526
void isAuthor() {
1627
// given
17-
Long applyId = 1L;
18-
UUID volunteerId = UUID.randomUUID();
19-
String title = "리뷰 제목";
20-
21-
Review review = createReview(applyId, volunteerId, title);
2228

2329
// when
2430
boolean result = review.isAuthor(volunteerId);
@@ -27,11 +33,41 @@ void isAuthor() {
2733
assertThat(result).isTrue();
2834
}
2935

30-
private Review createReview(Long applyId, UUID volunteerId, String title) {
36+
@DisplayName("리뷰 제목 내용을 업데이트 할 수 있다.")
37+
@Test
38+
void updateWith() {
39+
// given
40+
ReviewUpdateRequestDto dto = ReviewUpdateRequestDto.builder()
41+
.title("업데이트 제목")
42+
.content("업데이트 내용")
43+
.build();
44+
45+
// when
46+
review.updateWith(dto);
47+
48+
// then
49+
assertThat(review.getTitle()).isEqualTo(dto.title());
50+
assertThat(review.getContent()).isEqualTo(dto.content());
51+
}
52+
53+
@DisplayName("이미지 링크를 업데이트 할 수 있다.")
54+
@Test
55+
void updateWithImgUrl() {
56+
// given
57+
String newImgUrl = "newLink";
58+
59+
// when
60+
review.updateWith(newImgUrl);
61+
62+
// then
63+
assertThat(review.getImgUrl()).isEqualTo(newImgUrl);
64+
}
65+
66+
private Review createReview(Long applyId, UUID volunteerId) {
3167
return Review.builder()
3268
.volunteerApplyId(applyId)
3369
.volunteerId(volunteerId)
34-
.title(title)
70+
.title("제목제목")
3571
.content("내용내용")
3672
.imgUrl("이미지링크")
3773
.build();
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package com.somemore.domains.review.service;
2+
3+
import com.somemore.domains.review.domain.Review;
4+
import com.somemore.domains.review.dto.request.ReviewUpdateRequestDto;
5+
import com.somemore.domains.review.repository.ReviewRepository;
6+
import com.somemore.global.exception.NoSuchElementException;
7+
import com.somemore.support.IntegrationTestSupport;
8+
import org.junit.jupiter.api.BeforeEach;
9+
import org.junit.jupiter.api.DisplayName;
10+
import org.junit.jupiter.api.Test;
11+
import org.springframework.beans.factory.annotation.Autowired;
12+
import org.springframework.transaction.annotation.Transactional;
13+
14+
import java.util.UUID;
15+
16+
import static com.somemore.global.exception.ExceptionMessage.NOT_EXISTS_REVIEW;
17+
import static org.assertj.core.api.Assertions.assertThat;
18+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
19+
20+
@Transactional
21+
class UpdateReviewServiceTest extends IntegrationTestSupport {
22+
23+
@Autowired
24+
private UpdateReviewService updateReviewService;
25+
26+
@Autowired
27+
private ReviewRepository reviewRepository;
28+
29+
private UUID volunteerId;
30+
private Review review;
31+
32+
@BeforeEach
33+
void setUp() {
34+
volunteerId = UUID.randomUUID();
35+
review = createReview(1L, volunteerId);
36+
reviewRepository.save(review);
37+
}
38+
39+
@DisplayName("리뷰 정보를 업데이트 할 수 있다.")
40+
@Test
41+
void updateReview() {
42+
// given
43+
Long id = review.getId();
44+
ReviewUpdateRequestDto dto = ReviewUpdateRequestDto.builder()
45+
.title("업데이트 제목")
46+
.content("업데이트 내용")
47+
.build();
48+
49+
// when
50+
updateReviewService.updateReview(id, volunteerId, dto);
51+
52+
// then
53+
Review updateReview = reviewRepository.findById(id).orElseThrow();
54+
assertThat(updateReview.getTitle()).isEqualTo(dto.title());
55+
assertThat(updateReview.getContent()).isEqualTo(dto.content());
56+
}
57+
58+
@DisplayName("존재하지 않는 리뷰를 업데이트할 경우 에러가 발생한다.")
59+
@Test
60+
void updateReviewWhenDoesNotExistId() {
61+
// given
62+
Long wrongId = 999L;
63+
64+
ReviewUpdateRequestDto dto = ReviewUpdateRequestDto.builder()
65+
.title("업데이트 제목")
66+
.content("업데이트 내용")
67+
.build();
68+
69+
// when
70+
// then
71+
assertThatThrownBy(
72+
() -> updateReviewService.updateReview(wrongId, volunteerId, dto))
73+
.isInstanceOf(NoSuchElementException.class)
74+
.hasMessage(NOT_EXISTS_REVIEW.getMessage());
75+
}
76+
77+
@DisplayName("리뷰 이미지 링크를 업데이트 할 수 있다.")
78+
@Test
79+
void updateReviewImageUrl() {
80+
// given
81+
Long id = review.getId();
82+
String newImgUrl = "newLink.co.kr";
83+
84+
// when
85+
updateReviewService.updateReviewImageUrl(id, volunteerId, newImgUrl);
86+
87+
// then
88+
Review updateReview = reviewRepository.findById(id).orElseThrow();
89+
assertThat(updateReview.getImgUrl()).isEqualTo(newImgUrl);
90+
}
91+
92+
@DisplayName("존재하지 않는 리뷰의 이미지링크를 업데이트할 경우 에러가 발생한다.")
93+
@Test
94+
void updateReviewImageUrlWhenDoesNotExistId() {
95+
// given
96+
Long wrongId = 999L;
97+
String newImgUrl = "newLink.co.kr";
98+
99+
// when
100+
// then
101+
assertThatThrownBy(
102+
() -> updateReviewService.updateReviewImageUrl(wrongId, volunteerId, newImgUrl))
103+
.isInstanceOf(NoSuchElementException.class)
104+
.hasMessage(NOT_EXISTS_REVIEW.getMessage());
105+
}
106+
107+
private Review createReview(Long applyId, UUID volunteerId) {
108+
return Review.builder()
109+
.volunteerApplyId(applyId)
110+
.volunteerId(volunteerId)
111+
.title("제목제목")
112+
.content("내용내용")
113+
.imgUrl("이미지링크")
114+
.build();
115+
}
116+
}

0 commit comments

Comments
 (0)