Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -36,7 +39,6 @@ public ResponseEntity<CommentDto> createComment(
}

@PatchMapping("/{commentId}")
@ResponseStatus(HttpStatus.OK)
public ResponseEntity<CommentDto> updateComment(
@PathVariable @Positive Long userId,
@PathVariable @Positive Long commentId,
Expand All @@ -47,4 +49,17 @@ public ResponseEntity<CommentDto> updateComment(

return ResponseEntity.status(HttpStatus.OK).body(commentService.updateUserComment(userId, commentId, updateCommentDto));
}

@GetMapping
public ResponseEntity<List<CommentDto>> getUserComments(
@PathVariable @Positive Long userId,
@RequestParam(defaultValue = "0") @PositiveOrZero int from,
@RequestParam(defaultValue = "10") @Positive int size) {

List<CommentDto> result = commentService.getUserComments(userId, from, size);

log.info("Получение списка комментариев {} пользователя c id {}", result, userId);

return ResponseEntity.status(HttpStatus.OK).body(result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ public interface CommentRepository extends JpaRepository<Comment, Long> {
@EntityGraph(attributePaths = {"author"})
Page<Comment> findByEventIdAndIsDeletedFalse(Long eventId, Pageable pageable);

@EntityGraph(attributePaths = {"author"})
Page<Comment> findByAuthorIdAndIsDeletedFalse(Long authorId, Pageable pageable);

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public interface CommentService {

List<CommentDto> getCommentsForEvent(Long eventId, PublicCommentParameters commentParameters);

List<CommentDto> getUserComments(Long userId, int from, int size);

CommentDto addComment(Long userId, Long eventId, NewCommentDto newCommentDto);

CommentDto updateUserComment(Long userId, Long commentId, UpdateCommentDto updateCommentDto);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -52,6 +53,22 @@ public List<CommentDto> getCommentsForEvent(Long eventId, PublicCommentParameter
return commentMapper.toDtoList(result);
}

@Override
@Transactional(readOnly = true)
public List<CommentDto> 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<Comment> result = commentRepository.findByAuthorIdAndIsDeletedFalse(userId, pageable).getContent();

return commentMapper.toDtoList(result);
}

@Override
@Transactional
public CommentDto addComment(Long userId, Long eventId, NewCommentDto newCommentDto) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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<CommentDto> 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());
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.*;

Expand Down Expand Up @@ -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<CommentDto> 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<Comment> comments = List.of(comment);
CommentDto commentDto = new CommentDto();
List<CommentDto> 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<CommentDto> 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);
}
}
}