Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/242 커뮤니티 게시글 검색 조회 (RDB) #248

Merged
merged 6 commits into from
Dec 18, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public ApiResponse<Page<CommunityBoardResponseDto>> getAll(
) {
return ApiResponse.ok(
200,
communityBoardQueryUseCase.getCommunityBoards(pageable.getPageNumber()),
communityBoardQueryUseCase.getCommunityBoards(null, pageable.getPageNumber()),
"전체 커뮤니티 게시글 리스트 조회 성공"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null이 조금 걸리는데 제가 했던 SearchCondition 이라는 Dto를 만들어서 Paging까지 같이 넣는거 어떻게 생각하시나요??
다른분들 의견도 궁금합니다~

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 좋습니다

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

condition이 단순해보이는데 builder가 아니라 생성자를 이용하는건 어떨까요

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

빌더 만들고 paging만 넣어두는 식으로 하면 괜찮을 것 같아요

);
}
Expand Down Expand Up @@ -61,6 +61,19 @@ public ApiResponse<Page<CommunityBoardResponseDto>> getByWriterId(
// );
// }

@GetMapping("/community-boards/search")
@Operation(summary = "커뮤니티 게시글 키워드 검색", description = "키워드를 포함한 커뮤니티 게시글 목록을 조회합니다.")
public ApiResponse<Page<CommunityBoardResponseDto>> getCommunityBoardsBySearch(
@RequestParam String keyword,
Pageable pageable
) {
return ApiResponse.ok(
200,
communityBoardQueryUseCase.getCommunityBoards(keyword, pageable.getPageNumber()),
"커뮤니티 게시글 검색 리스트 조회 성공"
);
}

@GetMapping("/community-board/{id}")
@Operation(summary = "커뮤니티 게시글 상세 조회", description = "커뮤니티 게시글의 상세 정보를 조회합니다.")
public ApiResponse<CommunityBoardDetailResponseDto> getById(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public interface CommunityBoardRepository {
CommunityBoard save(CommunityBoard communityBoard);
Optional<CommunityBoard> findById(Long id);
Page<CommunityBoardView> findCommunityBoards(Pageable pageable);
Page<CommunityBoardView> findCommunityBoards(String keyword, Pageable pageable);
Page<CommunityBoardView> findByWriterId(UUID writerId, Pageable pageable);
boolean existsById(Long id);
default boolean doesNotExistById(Long id) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.somemore.community.domain.QCommunityBoard;
import com.somemore.volunteer.domain.QVolunteer;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일부러 이거 쓰신건가요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

범수님 코드 참고했는데 이렇게 StringUtils의 isNotBlank 사용해서 체크하셨던데
if문 보다 깔끔하다고 생각했고 통일하면 좋을 거 같아서 똑같이 했습니다!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다~ 좋은 것 같아요
저희가 만들지 않은 유틸 클래스를 사용하는 것을 처음봐서 여쭤봤습니다

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isNotBlank 메서드가 null 체크, ""문자열 체크, " ", 공백 체크까지해서 자주 애용하고 있습니다 좋아요

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@leebs0521 저희만의 유틸 인터페이스를 만들고 구현체에 아파치의 스트링 유틸을 사용하는 것은 과한걸까요? 갑자기 궁금해져서 여쭤봅니다.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@m-a-king 음... 그렇게 생각하신 이유가 있을까요?? 저는 일단 과하다라고 느껴지긴하네용

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다음 기회에...

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.support.PageableExecutionUtils;
Expand Down Expand Up @@ -44,9 +45,10 @@ public Optional<CommunityBoard> findById(Long id) {
}

@Override
public Page<CommunityBoardView> findCommunityBoards(Pageable pageable) {
public Page<CommunityBoardView> findCommunityBoards(String keyword, Pageable pageable) {
List<CommunityBoardView> content = getCommunityBoardsQuery()
.where(isNotDeleted())
.where(isNotDeleted()
.and(keywordEq(keyword)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isNotDeleted가 앞에 있는건 혹시 조인 때문인건가요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keywordEq이 먼저 오는게 맞을 거 같아서 수정하겠습니다!

.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
Expand All @@ -55,7 +57,8 @@ public Page<CommunityBoardView> findCommunityBoards(Pageable pageable) {
.select(communityBoard.count())
.from(communityBoard)
.join(volunteer).on(communityBoard.writerId.eq(volunteer.id))
.where(isNotDeleted());
.where(isNotDeleted()
.and(keywordEq(keyword)));

return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchOne);
}
Expand Down Expand Up @@ -160,6 +163,12 @@ private BooleanExpression isNotDeleted() {

private BooleanExpression isWriter(UUID writerId) {return communityBoard.writerId.eq(writerId); }

private BooleanExpression keywordEq(String keyword) {
return StringUtils.isNotBlank(keyword)
? communityBoard.title.containsIgnoreCase(
keyword) : null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return StringUtils.isNotBlank(keyword)
? communityBoard.title.containsIgnoreCase(
keyword) : null;
return StringUtils.isNotBlank(keyword)
? communityBoard.title.containsIgnoreCase(keyword)
: null;

이렇게 쓸 수 있을 것 같아요~~

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null까지 다 한줄로 올리는게 나을까요 null은 내리는 게 나을까요?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return에 삼항연산을 사용할 때, : 기준으로 개행하긴 하던데 아영 님 편한 대로 하셔도 될 것 같아요

}

// private List<CommunityBoardDocument> getBoardDocuments(String keyword) {
//
// if (keyword == null || keyword.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public class CommunityBoardQueryService implements CommunityBoardQueryUseCase {
private static final int PAGE_SIZE = 10;

@Override
public Page<CommunityBoardResponseDto> getCommunityBoards(int page) {
public Page<CommunityBoardResponseDto> getCommunityBoards(String keyword, int page) {
Pageable pageable = PageRequest.of(page, PAGE_SIZE);
Page<CommunityBoardView> boards = communityBoardRepository.findCommunityBoards(pageable);
Page<CommunityBoardView> boards = communityBoardRepository.findCommunityBoards(keyword, pageable);
return boards.map(CommunityBoardResponseDto::from);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import java.util.UUID;

public interface CommunityBoardQueryUseCase {
Page<CommunityBoardResponseDto> getCommunityBoards(int page);
Page<CommunityBoardResponseDto> getCommunityBoards(String keyword, int page);
Page<CommunityBoardResponseDto> getCommunityBoardsByWriterId(UUID writerId, int page);
CommunityBoardDetailResponseDto getCommunityBoardDetail(Long id);
List<CommunityBoard> getAllCommunityBoards();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void getAll() throws Exception {
//given
Page<CommunityBoardResponseDto> page = new PageImpl<>(Collections.emptyList());

given(communityBoardQueryUseCase.getCommunityBoards(anyInt()))
given(communityBoardQueryUseCase.getCommunityBoards(any(), anyInt()))
.willReturn(page);

//when
Expand All @@ -56,7 +56,7 @@ void getAll() throws Exception {
.value("전체 커뮤니티 게시글 리스트 조회 성공"));

verify(communityBoardQueryUseCase, times(1))
.getCommunityBoards(anyInt());
.getCommunityBoards(any(), anyInt());
}

@Test
Expand Down Expand Up @@ -106,6 +106,29 @@ void getById() throws Exception {
.getCommunityBoardDetail(any());
}

@Test
@DisplayName("커뮤니티 게시글 검색 조회 성공")
void getBySearch() throws Exception {
//given
Page<CommunityBoardResponseDto> page = new PageImpl<>(Collections.emptyList());

given(communityBoardQueryUseCase.getCommunityBoards(any(), anyInt()))
.willReturn(page);
//when
//then
mockMvc.perform(get("/api/community-boards/search")
.param("keyword", "봉사")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(200))
.andExpect(jsonPath("$.data").exists())
.andExpect(jsonPath("$.message")
.value("커뮤니티 게시글 검색 리스트 조회 성공"));

verify(communityBoardQueryUseCase, times(1))
.getCommunityBoards(any(), anyInt());
}

// @Test
// @DisplayName("커뮤니티 게시글 검색 조회 성공")
// void getBySearch() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void getCommunityBoards() {
Pageable pageable = getPageable();

//when
Page<CommunityBoardView> communityBoards = communityBoardRepository.findCommunityBoards(pageable);
Page<CommunityBoardView> communityBoards = communityBoardRepository.findCommunityBoards(null, pageable);

//then
assertThat(communityBoards).isNotNull();
Expand Down Expand Up @@ -138,6 +138,27 @@ void existsById() {
assertThat(isExist).isTrue();
}

@DisplayName("검색 키워드가 포함된 커뮤니티 게시글을 페이지로 조회할 수 있다. (Repository)")
@Test
void getCommunityBoardsBySearch() {

//given
Pageable pageable = getPageable();

String title = "봉사";
CommunityBoard communityBoard = createCommunityBoard(title, writerId);
communityBoardRepository.save(communityBoard);

//when
Page<CommunityBoardView> communityBoards = communityBoardRepository.findCommunityBoards("봉사", pageable);

//then
assertThat(communityBoards).isNotNull();
assertThat(communityBoards.getTotalElements()).isEqualTo(1);
assertThat(communityBoards.getSize()).isEqualTo(10);
assertThat(communityBoards.getNumber()).isZero();
}

// @DisplayName("게시글을 elastic search index에 저장할 수 있다. (repository)")
// @Test
// void saveDocuments() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void getAllCommunityBoards() {

//given
//when
Page<CommunityBoardResponseDto> dtos = communityBoardQueryService.getCommunityBoards(2);
Page<CommunityBoardResponseDto> dtos = communityBoardQueryService.getCommunityBoards(null, 2);

//then
assertThat(dtos).isNotNull();
Expand Down Expand Up @@ -149,6 +149,26 @@ void getCommunityBoardDetailWithDeletedId() {
.withMessage(ExceptionMessage.NOT_EXISTS_COMMUNITY_BOARD.getMessage());
}

@DisplayName("검색 키워드가 포함된 커뮤니티 게시글 리스트를 페이지로 조회한다.")
@Test
void getCommunityBoardsBySearch() {

//given
String title = "봉사";
CommunityBoard communityBoard = createCommunityBoard(title, writerId1);
communityBoardRepository.save(communityBoard);

//when
Page<CommunityBoardResponseDto> dtos = communityBoardQueryService.getCommunityBoards("봉사", 0);

//then
assertThat(dtos).isNotNull();
assertThat(dtos.getContent()).isNotNull();
assertThat(dtos.getTotalElements()).isEqualTo(1);
assertThat(dtos.getSize()).isEqualTo(10);
assertThat(dtos.getTotalPages()).isEqualTo(1);
}

// @DisplayName("게시글을 elastic search index에 저장한다. (service)")
// @Test
// void saveCommunityBoardDocuments() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ void deleteCommunityBoardWithId() {
deleteCommunityBoardService.deleteCommunityBoard(writerId, communityId);

//then
assertThat(communityBoardQueryUseCase.getCommunityBoards(0)).isEmpty();
assertThat(communityBoardQueryUseCase.getCommunityBoards(null, 0)).isEmpty();
}

@DisplayName("삭제된 커뮤니티 게시글의 id로 게시글을 삭제할 때 예외를 던진다.")
Expand Down
Loading