diff --git a/main-service/src/main/java/ru/practicum/explorewithme/main/controller/priv/PrivateCommentController.java b/main-service/src/main/java/ru/practicum/explorewithme/main/controller/priv/PrivateCommentController.java index c14849b..81e9856 100644 --- a/main-service/src/main/java/ru/practicum/explorewithme/main/controller/priv/PrivateCommentController.java +++ b/main-service/src/main/java/ru/practicum/explorewithme/main/controller/priv/PrivateCommentController.java @@ -2,6 +2,7 @@ import jakarta.validation.Valid; import jakarta.validation.constraints.Positive; +import jakarta.validation.constraints.PositiveOrZero; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; @@ -13,6 +14,8 @@ import ru.practicum.explorewithme.main.dto.UpdateCommentDto; import ru.practicum.explorewithme.main.service.CommentService; +import java.util.List; + @RestController @RequestMapping("/users/{userId}/comments") @RequiredArgsConstructor @@ -36,7 +39,6 @@ public ResponseEntity createComment( } @PatchMapping("/{commentId}") - @ResponseStatus(HttpStatus.OK) public ResponseEntity updateComment( @PathVariable @Positive Long userId, @PathVariable @Positive Long commentId, @@ -47,4 +49,17 @@ public ResponseEntity updateComment( return ResponseEntity.status(HttpStatus.OK).body(commentService.updateUserComment(userId, commentId, updateCommentDto)); } + + @GetMapping + public ResponseEntity> getUserComments( + @PathVariable @Positive Long userId, + @RequestParam(defaultValue = "0") @PositiveOrZero int from, + @RequestParam(defaultValue = "10") @Positive int size) { + + List result = commentService.getUserComments(userId, from, size); + + log.info("Получение списка комментариев {} пользователя c id {}", result, userId); + + return ResponseEntity.status(HttpStatus.OK).body(result); + } } diff --git a/main-service/src/main/java/ru/practicum/explorewithme/main/repository/CommentRepository.java b/main-service/src/main/java/ru/practicum/explorewithme/main/repository/CommentRepository.java index 4977c33..87fc9c8 100644 --- a/main-service/src/main/java/ru/practicum/explorewithme/main/repository/CommentRepository.java +++ b/main-service/src/main/java/ru/practicum/explorewithme/main/repository/CommentRepository.java @@ -12,4 +12,7 @@ public interface CommentRepository extends JpaRepository { @EntityGraph(attributePaths = {"author"}) Page findByEventIdAndIsDeletedFalse(Long eventId, Pageable pageable); + @EntityGraph(attributePaths = {"author"}) + Page findByAuthorIdAndIsDeletedFalse(Long authorId, Pageable pageable); + } \ No newline at end of file diff --git a/main-service/src/main/java/ru/practicum/explorewithme/main/service/CommentService.java b/main-service/src/main/java/ru/practicum/explorewithme/main/service/CommentService.java index 79bce6a..68e888a 100644 --- a/main-service/src/main/java/ru/practicum/explorewithme/main/service/CommentService.java +++ b/main-service/src/main/java/ru/practicum/explorewithme/main/service/CommentService.java @@ -11,6 +11,8 @@ public interface CommentService { List getCommentsForEvent(Long eventId, PublicCommentParameters commentParameters); + List getUserComments(Long userId, int from, int size); + CommentDto addComment(Long userId, Long eventId, NewCommentDto newCommentDto); CommentDto updateUserComment(Long userId, Long commentId, UpdateCommentDto updateCommentDto); diff --git a/main-service/src/main/java/ru/practicum/explorewithme/main/service/CommentServiceImpl.java b/main-service/src/main/java/ru/practicum/explorewithme/main/service/CommentServiceImpl.java index 6c6e63d..c3fa85c 100644 --- a/main-service/src/main/java/ru/practicum/explorewithme/main/service/CommentServiceImpl.java +++ b/main-service/src/main/java/ru/practicum/explorewithme/main/service/CommentServiceImpl.java @@ -3,6 +3,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import ru.practicum.explorewithme.main.dto.CommentDto; @@ -52,6 +53,22 @@ public List getCommentsForEvent(Long eventId, PublicCommentParameter return commentMapper.toDtoList(result); } + @Override + @Transactional(readOnly = true) + public List getUserComments(Long userId, int from, int size) { + + if (!userRepository.existsById(userId)) { + throw new EntityNotFoundException("Пользователь с id " + userId + " не найден"); + } + + Sort sort = Sort.by(Sort.Direction.DESC, "createdOn"); + Pageable pageable = PageRequest.of(from / size, size, sort); + + List result = commentRepository.findByAuthorIdAndIsDeletedFalse(userId, pageable).getContent(); + + return commentMapper.toDtoList(result); + } + @Override @Transactional public CommentDto addComment(Long userId, Long eventId, NewCommentDto newCommentDto) { diff --git a/main-service/src/test/java/ru/practicum/explorewithme/main/controller/priv/PrivateCommentControllerTest.java b/main-service/src/test/java/ru/practicum/explorewithme/main/controller/priv/PrivateCommentControllerTest.java index d6d7cf5..88f0583 100644 --- a/main-service/src/test/java/ru/practicum/explorewithme/main/controller/priv/PrivateCommentControllerTest.java +++ b/main-service/src/test/java/ru/practicum/explorewithme/main/controller/priv/PrivateCommentControllerTest.java @@ -17,14 +17,13 @@ import ru.practicum.explorewithme.main.service.CommentService; import java.time.LocalDateTime; +import java.util.List; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; // <-- для post-запроса -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @WebMvcTest(PrivateCommentController.class) @@ -213,4 +212,60 @@ void updateComment_shouldReturnBadRequest_whenBodyEmpty() throws Exception { .andExpect(jsonPath("$.errors[0]").value("text: Comment text cannot be blank.")); } } + + @Nested + @DisplayName("Набор тестов для метода getUserComments") + class GetUserComments { + + @Test + void getUserCommentsReturnsCommentsListWithStatusOk() throws Exception { + + List comments = List.of(commentDto); + + when(commentService.getUserComments(userId, 0, 10)).thenReturn(comments); + + mockMvc.perform(get("/users/{userId}/comments", userId) + .param("from", "0") + .param("size", "10") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json(objectMapper.writeValueAsString(comments))); + + verify(commentService, times(1)).getUserComments(userId, 0, 10); + } + + @Test + void getUserCommentsReturnsEmptyListWhenNoComments() throws Exception { + + when(commentService.getUserComments(userId, 0, 10)).thenReturn(List.of()); + + mockMvc.perform(get("/users/{userId}/comments", userId) + .param("from", "0") + .param("size", "10") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json("[]")); + } + + @Test + void getUserCommentsReturnsBadRequestWhenFromIsNegative() throws Exception { + + mockMvc.perform(get("/users/{userId}/comments", userId) + .param("from", "-1") + .param("size", "10") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + } + + @Test + void getUserCommentsReturnsBadRequestWhenSizeIsZero() throws Exception { + + mockMvc.perform(get("/users/{userId}/comments", userId) + .param("from", "0") + .param("size", "0") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()); + } + + } } diff --git a/main-service/src/test/java/ru/practicum/explorewithme/main/service/CommentServiceImplTest.java b/main-service/src/test/java/ru/practicum/explorewithme/main/service/CommentServiceImplTest.java index 7ebbc11..78394c9 100644 --- a/main-service/src/test/java/ru/practicum/explorewithme/main/service/CommentServiceImplTest.java +++ b/main-service/src/test/java/ru/practicum/explorewithme/main/service/CommentServiceImplTest.java @@ -5,6 +5,8 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import ru.practicum.explorewithme.main.dto.CommentDto; import ru.practicum.explorewithme.main.dto.NewCommentDto; import ru.practicum.explorewithme.main.dto.UpdateCommentDto; @@ -20,8 +22,10 @@ import ru.practicum.explorewithme.main.repository.UserRepository; import java.time.LocalDateTime; +import java.util.List; import java.util.Optional; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @@ -216,4 +220,62 @@ void updateUserComment_shouldThrowIfTooLate() { Assertions.assertTrue(ex.getMessage().contains("Время для редактирования истекло")); } } + + @Nested + @DisplayName("Набор тестов для метода getUserComments") + class GetUserComments { + + @Test + void getUserCommentsshouldReturnEmptyListwhenNoComments() { + + when(userRepository.existsById(userId)).thenReturn(true); + when(commentRepository.findByAuthorIdAndIsDeletedFalse(eq(userId), any(Pageable.class))) + .thenReturn(new PageImpl<>(List.of())); + when(commentMapper.toDtoList(List.of())).thenReturn(List.of()); + + List result = commentService.getUserComments(userId, 0, 10); + + assertThat(result).isEmpty(); + + verify(userRepository).existsById(userId); + verify(commentRepository).findByAuthorIdAndIsDeletedFalse(eq(userId), any(Pageable.class)); + verify(commentMapper).toDtoList(List.of()); + } + + @Test + void getUserCommentsshouldReturnCommentsDtoListwhenCommentsExist() { + + List comments = List.of(comment); + CommentDto commentDto = new CommentDto(); + List commentDtos = List.of(commentDto); + + when(userRepository.existsById(userId)).thenReturn(true); + when(commentRepository.findByAuthorIdAndIsDeletedFalse(eq(userId), any(Pageable.class))) + .thenReturn(new PageImpl<>(comments)); + when(commentMapper.toDtoList(comments)).thenReturn(commentDtos); + + List result = commentService.getUserComments(userId, 0, 10); + + assertThat(result).isEqualTo(commentDtos); + + verify(userRepository).existsById(userId); + verify(commentRepository).findByAuthorIdAndIsDeletedFalse(eq(userId), any(Pageable.class)); + verify(commentMapper).toDtoList(comments); + } + + @Test + void getUserCommentsshouldThrowExceptionwhenUserNotFound() { + + when(userRepository.existsById(userId)).thenReturn(false); + + EntityNotFoundException exception = assertThrows( + EntityNotFoundException.class, + () -> commentService.getUserComments(userId, 0, 10) + ); + + assertThat(exception.getMessage()).contains("Пользователь с id " + userId + " не найден"); + verify(userRepository).existsById(userId); + verifyNoInteractions(commentRepository, commentMapper); + } + } } \ No newline at end of file