From 98b3ae376b260d41704c381f49b607fbc26e271c Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 01:18:16 +0900 Subject: [PATCH 01/23] =?UTF-8?q?feature(search):=20elasticsearch=20?= =?UTF-8?q?=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 ++ src/main/resources/application.yml | 15 +++++++++++++++ src/test/resources/application-test.yml | 17 ++++++++++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c82330d96..eade7e24a 100644 --- a/build.gradle +++ b/build.gradle @@ -67,6 +67,8 @@ dependencies { implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.6.0' implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: '3.3.3' + //elastic-search + implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch' //test testImplementation 'org.springframework.boot:spring-boot-starter-test' diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index b350d50cd..9c220f2e5 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -41,6 +41,10 @@ spring: port: ${REDIS_PORT} password: ${REDIS_PASSWORD} + elasticsearch: + repositories: + enabled: true + security: oauth2: client: @@ -105,3 +109,14 @@ server: default: image: url: ${DEFAULT_IMG_URL} + +elastic: + search: + uris: ${ELASTIC_URI} + username: ${ELASTIC_USERNAME} + password: ${ELASTIC_PASSWORD} + +management: + health: + elasticsearch: + enabled: false diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml index 537ef65eb..00940b63f 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application-test.yml @@ -33,6 +33,10 @@ spring: port: 6379 password: # 테스트에서는 비밀번호 없이 연결 + elasticsearch: + repositories: + enabled: true + web: locale: ko_KR locale-resolver: fixed @@ -56,10 +60,21 @@ cloud: static: ap-northeast-2 s3: bucket: somemore - base-url: https://somemore-image.s3.ap-northeast-2.amazonaws.com + base-url: https://somemore-images.s3.ap-northeast-2.amazonaws.com/ stack: auto: false default: image: url: "" + +elastic: + search: + uris: localhost:9200 + username: elastic + password: somemore + +management: + health: + elasticsearch: + enabled: false From 65bc207b3eb2388fe5856bce24d48f4d04383e2c Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 01:20:35 +0900 Subject: [PATCH 02/23] =?UTF-8?q?feature(search):=20elasticsearch=20docume?= =?UTF-8?q?nt,=20repository=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/CommunityBoardDocument.java | 29 ++++++++++++++++++ .../CommunityBoardDocumentRepository.java | 12 ++++++++ .../domain/RecruitBoardDocument.java | 30 +++++++++++++++++++ .../RecruitBoardDocumentRepository.java | 12 ++++++++ 4 files changed, 83 insertions(+) create mode 100644 src/main/java/com/somemore/community/domain/CommunityBoardDocument.java create mode 100644 src/main/java/com/somemore/community/repository/board/CommunityBoardDocumentRepository.java create mode 100644 src/main/java/com/somemore/recruitboard/domain/RecruitBoardDocument.java create mode 100644 src/main/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepository.java diff --git a/src/main/java/com/somemore/community/domain/CommunityBoardDocument.java b/src/main/java/com/somemore/community/domain/CommunityBoardDocument.java new file mode 100644 index 000000000..c031e0e58 --- /dev/null +++ b/src/main/java/com/somemore/community/domain/CommunityBoardDocument.java @@ -0,0 +1,29 @@ +package com.somemore.community.domain; + +import jakarta.persistence.Id; +import lombok.Builder; +import lombok.Getter; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; + +@Getter +@Document(indexName = "community_board") +public class CommunityBoardDocument { + + @Id + private Long id; + + @Field(type = FieldType.Text, analyzer = "nori_analyzer") + private String title; + + @Field(type = FieldType.Text, analyzer = "nori_analyzer") + private String content; + + @Builder + public CommunityBoardDocument(Long id, String title, String content) { + this.id = id; + this.title = title; + this.content = content; + } +} diff --git a/src/main/java/com/somemore/community/repository/board/CommunityBoardDocumentRepository.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardDocumentRepository.java new file mode 100644 index 000000000..41241b1c1 --- /dev/null +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardDocumentRepository.java @@ -0,0 +1,12 @@ +package com.somemore.community.repository.board; + +import com.somemore.community.domain.CommunityBoardDocument; +import org.springframework.data.elasticsearch.annotations.Query; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; + +import java.util.List; + +public interface CommunityBoardDocumentRepository extends ElasticsearchRepository { + @Query("{\"multi_match\": {\"query\": \"?0\", \"fields\": [\"title\", \"content\"]}}") + List findIdsByTitleOrContentContaining(String keyword); +} diff --git a/src/main/java/com/somemore/recruitboard/domain/RecruitBoardDocument.java b/src/main/java/com/somemore/recruitboard/domain/RecruitBoardDocument.java new file mode 100644 index 000000000..e95aa422f --- /dev/null +++ b/src/main/java/com/somemore/recruitboard/domain/RecruitBoardDocument.java @@ -0,0 +1,30 @@ +package com.somemore.recruitboard.domain; + +import jakarta.persistence.Id; +import lombok.Builder; +import lombok.Getter; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; + +@Getter +@Document(indexName = "recruit_board") +public class RecruitBoardDocument { + + @Id + private Long id; + + @Field(type = FieldType.Text, analyzer = "nori_analyzer") + private String title; + + @Field(type = FieldType.Text, analyzer = "nori_analyzer") + private String content; + + + @Builder + public RecruitBoardDocument(Long id, String title, String content) { + this.id = id; + this.title = title; + this.content = content; + } +} \ No newline at end of file diff --git a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepository.java b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepository.java new file mode 100644 index 000000000..aaa0fe9b6 --- /dev/null +++ b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepository.java @@ -0,0 +1,12 @@ +package com.somemore.recruitboard.repository; + +import com.somemore.recruitboard.domain.RecruitBoardDocument; +import org.springframework.data.elasticsearch.annotations.Query; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; + +import java.util.List; + +public interface RecruitBoardDocumentRepository extends ElasticsearchRepository { + @Query("{\"multi_match\": {\"query\": \"?0\", \"fields\": [\"title\", \"content\"]}}") + List findIdsByTitleOrContentContaining(String keyword); +} From ca23f9603a391cf8eb45c80e53f29cc8723b5072 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 01:23:46 +0900 Subject: [PATCH 03/23] =?UTF-8?q?feature(search):=20repository=EC=97=90=20?= =?UTF-8?q?elasticsearch=20=EA=B4=80=EB=A0=A8=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - keyword로 검색 결과 반환 - elasticsearch에 저장 - 전체 데이터 조회 - elasticsearch 데이터 삭제 --- .../board/CommunityBoardRepository.java | 6 ++ .../board/CommunityBoardRepositoryImpl.java | 64 +++++++++++++++- .../repository/RecruitBoardRepository.java | 5 ++ .../RecruitBoardRepositoryImpl.java | 75 ++++++++++++++++++- 4 files changed, 142 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java index e767e837c..3e37727b7 100644 --- a/src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepository.java @@ -5,6 +5,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import java.util.List; import java.util.Optional; import java.util.UUID; @@ -18,4 +19,9 @@ default boolean doesNotExistById(Long id) { return !existsById(id); } void deleteAllInBatch(); + + Page findByCommunityBoardsContaining(String keyword, Pageable pageable); + void saveDocuments(List communityBoards); + List findAll(); + void deleteDocument(Long id); } diff --git a/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java index 0450c7630..48ccccb1d 100644 --- a/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java @@ -5,6 +5,7 @@ import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; import com.somemore.community.domain.CommunityBoard; +import com.somemore.community.domain.CommunityBoardDocument; import com.somemore.community.repository.mapper.CommunityBoardView; import com.somemore.community.domain.QCommunityBoard; import com.somemore.volunteer.domain.QVolunteer; @@ -14,6 +15,7 @@ import org.springframework.data.support.PageableExecutionUtils; import org.springframework.stereotype.Repository; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -24,6 +26,7 @@ public class CommunityBoardRepositoryImpl implements CommunityBoardRepository { private final JPAQueryFactory queryFactory; private final CommunityBoardJpaRepository communityBoardJpaRepository; + private final CommunityBoardDocumentRepository documentRepository; private static final QCommunityBoard communityBoard = QCommunityBoard.communityBoard; private static final QVolunteer volunteer = QVolunteer.volunteer; @@ -83,6 +86,51 @@ public boolean existsById(Long id) { return communityBoardJpaRepository.existsByIdAndDeletedFalse(id); } + @Override + public Page findByCommunityBoardsContaining(String keyword, Pageable pageable) { + List boardDocuments = documentRepository.findIdsByTitleOrContentContaining(keyword); + + List boardIds = boardDocuments.stream() + .map(CommunityBoardDocument::getId) + .toList(); + + List content = getCommunityBoardsQuery() + .where(communityBoard.id.in(boardIds) + .and(isNotDeleted())) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + JPAQuery countQuery = queryFactory + .select(communityBoard.count()) + .from(communityBoard) + .join(volunteer).on(communityBoard.writerId.eq(volunteer.id)) + .where(communityBoard.id.in(boardIds)); + + return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchOne); + } + + @Override + public void saveDocuments(List communityBoards) { + List communityBoardDocuments = convertEntityToDocuments(communityBoards); + documentRepository.saveAll(communityBoardDocuments); + } + + @Override + public void deleteDocument(Long id) { + documentRepository.deleteById(id); + } + + @Override + public List findAll() { + return communityBoardJpaRepository.findAll(); + } + + @Override + public void deleteAllInBatch() { + communityBoardJpaRepository.deleteAllInBatch(); + } + private JPAQuery getCommunityBoardsQuery() { return queryFactory .select(Projections.constructor(CommunityBoardView.class, @@ -93,10 +141,18 @@ private JPAQuery getCommunityBoardsQuery() { .orderBy(communityBoard.createdAt.desc()); } - - @Override - public void deleteAllInBatch() { - communityBoardJpaRepository.deleteAllInBatch(); + private List convertEntityToDocuments(List communityBoards) { + List communityBoardDocuments = new ArrayList<>(); + + for (CommunityBoard communityboard : communityBoards) { + CommunityBoardDocument document = CommunityBoardDocument.builder() + .id(communityboard.getId()) + .title(communityboard.getTitle()) + .content(communityboard.getContent()) + .build(); + communityBoardDocuments.add(document); + } + return communityBoardDocuments; } private BooleanExpression isNotDeleted() { diff --git a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepository.java b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepository.java index 1f25c824d..b4b34c9f0 100644 --- a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepository.java +++ b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepository.java @@ -30,4 +30,9 @@ public interface RecruitBoardRepository { List findNotCompletedIdsByCenterId(UUID centerId); List findAllByIds(List ids); + + Page findByRecruitBoardsContaining(String keyword, RecruitBoardSearchCondition condition); + void saveDocuments(List recruitBoards); + List findAll(); + void deleteDocument(Long id); } diff --git a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImpl.java b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImpl.java index a2d68ede6..496c23124 100644 --- a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImpl.java +++ b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImpl.java @@ -12,15 +12,14 @@ import com.somemore.center.domain.QCenter; import com.somemore.location.domain.QLocation; import com.somemore.location.utils.GeoUtils; -import com.somemore.recruitboard.domain.QRecruitBoard; -import com.somemore.recruitboard.domain.RecruitBoard; -import com.somemore.recruitboard.domain.RecruitStatus; -import com.somemore.recruitboard.domain.VolunteerCategory; +import com.somemore.recruitboard.domain.*; import com.somemore.recruitboard.dto.condition.RecruitBoardNearByCondition; import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; import com.somemore.recruitboard.repository.mapper.RecruitBoardDetail; import com.somemore.recruitboard.repository.mapper.RecruitBoardWithCenter; import com.somemore.recruitboard.repository.mapper.RecruitBoardWithLocation; + +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -37,6 +36,7 @@ public class RecruitBoardRepositoryImpl implements RecruitBoardRepository { private final RecruitBoardJpaRepository recruitBoardJpaRepository; + private final RecruitBoardDocumentRepository documentRepository; private final JPAQueryFactory queryFactory; @Override @@ -196,6 +196,60 @@ public Page findAllByCenterId(UUID centerId, return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchOne); } + @Override + public Page findByRecruitBoardsContaining(String keyword, RecruitBoardSearchCondition condition) { + QRecruitBoard recruitBoard = QRecruitBoard.recruitBoard; + QCenter center = QCenter.center; + + List boardDocuments = documentRepository.findIdsByTitleOrContentContaining(keyword); + + List boardIds = boardDocuments.stream() + .map(RecruitBoardDocument::getId) + .toList(); + + Pageable pageable = condition.pageable(); + BooleanExpression predicate = isNotDeleted() + .and(volunteerCategoryEq(condition.category())) + .and(regionEq(condition.region())) + .and(admittedEq(condition.admitted())) + .and(statusEq(condition.status())); + + List content = queryFactory + .select(getRecruitBoardWithCenterConstructorExpression(recruitBoard, center)) + .from(recruitBoard) + .where(recruitBoard.id.in(boardIds) + .and(predicate)) + .join(center).on(recruitBoard.centerId.eq(center.id)) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(toOrderSpecifiers(pageable.getSort())) + .fetch(); + + JPAQuery countQuery = queryFactory + .select(recruitBoard.count()) + .from(recruitBoard) + .join(center).on(recruitBoard.centerId.eq(center.id)) + .where(predicate); + + return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchOne); + } + + @Override + public void saveDocuments(List recruitBoards) { + List recruitBoardDocuments = convertEntityToDocuments(recruitBoards); + documentRepository.saveAll(recruitBoardDocuments); + } + + @Override + public List findAll() { + return recruitBoardJpaRepository.findAll(); + } + + @Override + public void deleteDocument(Long id) { + documentRepository.deleteById(id); + } + private static BooleanExpression idEq(Long id) { return recruitBoard.id.eq(id); } @@ -294,4 +348,17 @@ private static ConstructorExpression getRecruitBoardDetailCo recruitBoard, location.address, location.latitude, location.longitude, center.name); } + private List convertEntityToDocuments(List recruitBoards) { + List communityBoardDocuments = new ArrayList<>(); + + for (RecruitBoard recruitBoard : recruitBoards) { + RecruitBoardDocument document = RecruitBoardDocument.builder() + .id(recruitBoard.getId()) + .title(recruitBoard.getTitle()) + .content(recruitBoard.getContent()) + .build(); + communityBoardDocuments.add(document); + } + return communityBoardDocuments; + } } From 28e2990639da1ecf6b2e5d33663e71f6a4a25bca Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 01:28:40 +0900 Subject: [PATCH 04/23] =?UTF-8?q?feature(search):=20service=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - elasticsearch 저장 - elasticsearch 키워드 검색 - 전체글 조회 --- .../board/CommunityBoardDocumentService.java | 37 +++++++++++++++++++ .../board/CommunityBoardQueryService.java | 6 +++ .../board/CommunityBoardDocumentUseCase.java | 12 ++++++ .../board/CommunityBoardQueryUseCase.java | 3 ++ .../query/RecruitBoardDocumentService.java | 34 +++++++++++++++++ .../query/RecruitBoardQueryService.java | 4 ++ .../query/RecruitBoardDocumentUseCase.java | 13 +++++++ .../query/RecruitBoardQueryUseCase.java | 3 ++ 8 files changed, 112 insertions(+) create mode 100644 src/main/java/com/somemore/community/service/board/CommunityBoardDocumentService.java create mode 100644 src/main/java/com/somemore/community/usecase/board/CommunityBoardDocumentUseCase.java create mode 100644 src/main/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentService.java create mode 100644 src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardDocumentUseCase.java diff --git a/src/main/java/com/somemore/community/service/board/CommunityBoardDocumentService.java b/src/main/java/com/somemore/community/service/board/CommunityBoardDocumentService.java new file mode 100644 index 000000000..a53935563 --- /dev/null +++ b/src/main/java/com/somemore/community/service/board/CommunityBoardDocumentService.java @@ -0,0 +1,37 @@ +package com.somemore.community.service.board; + +import com.somemore.community.domain.CommunityBoard; +import com.somemore.community.dto.response.CommunityBoardResponseDto; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.repository.mapper.CommunityBoardView; +import com.somemore.community.usecase.board.CommunityBoardDocumentUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@RequiredArgsConstructor +@Service +public class CommunityBoardDocumentService implements CommunityBoardDocumentUseCase { + + private final CommunityBoardRepository communityBoardRepository; + private static final int PAGE_SIZE = 10; + + @Transactional(readOnly = true) + @Override + public Page getCommunityBoardBySearch(String keyword, int page) { + Pageable pageable = PageRequest.of(page, PAGE_SIZE); + Page boards = communityBoardRepository.findByCommunityBoardsContaining(keyword, pageable); + return boards.map(CommunityBoardResponseDto::from); + } + + @Transactional + @Override + public void saveCommunityBoardDocuments(List communityBoards) { + communityBoardRepository.saveDocuments(communityBoards); + } +} diff --git a/src/main/java/com/somemore/community/service/board/CommunityBoardQueryService.java b/src/main/java/com/somemore/community/service/board/CommunityBoardQueryService.java index 0e516630a..b91d50f22 100644 --- a/src/main/java/com/somemore/community/service/board/CommunityBoardQueryService.java +++ b/src/main/java/com/somemore/community/service/board/CommunityBoardQueryService.java @@ -14,6 +14,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.UUID; import static com.somemore.global.exception.ExceptionMessage.NOT_EXISTS_COMMUNITY_BOARD; @@ -46,4 +47,9 @@ public CommunityBoardDetailResponseDto getCommunityBoardDetail(Long id) { .orElseThrow(() -> new BadRequestException(NOT_EXISTS_COMMUNITY_BOARD.getMessage())); return CommunityBoardDetailResponseDto.from(board); } + + @Override + public List getAllCommunityBoards() { + return communityBoardRepository.findAll(); + } } diff --git a/src/main/java/com/somemore/community/usecase/board/CommunityBoardDocumentUseCase.java b/src/main/java/com/somemore/community/usecase/board/CommunityBoardDocumentUseCase.java new file mode 100644 index 000000000..86f7ca902 --- /dev/null +++ b/src/main/java/com/somemore/community/usecase/board/CommunityBoardDocumentUseCase.java @@ -0,0 +1,12 @@ +package com.somemore.community.usecase.board; + +import com.somemore.community.domain.CommunityBoard; +import com.somemore.community.dto.response.CommunityBoardResponseDto; +import org.springframework.data.domain.Page; + +import java.util.List; + +public interface CommunityBoardDocumentUseCase { + Page getCommunityBoardBySearch(String keyword, int page); + void saveCommunityBoardDocuments(List communityBoards); +} diff --git a/src/main/java/com/somemore/community/usecase/board/CommunityBoardQueryUseCase.java b/src/main/java/com/somemore/community/usecase/board/CommunityBoardQueryUseCase.java index 6e1d4c5c9..5a4011f85 100644 --- a/src/main/java/com/somemore/community/usecase/board/CommunityBoardQueryUseCase.java +++ b/src/main/java/com/somemore/community/usecase/board/CommunityBoardQueryUseCase.java @@ -1,13 +1,16 @@ package com.somemore.community.usecase.board; +import com.somemore.community.domain.CommunityBoard; import com.somemore.community.dto.response.CommunityBoardDetailResponseDto; import com.somemore.community.dto.response.CommunityBoardResponseDto; import org.springframework.data.domain.Page; +import java.util.List; import java.util.UUID; public interface CommunityBoardQueryUseCase { Page getCommunityBoards(int page); Page getCommunityBoardsByWriterId(UUID writerId, int page); CommunityBoardDetailResponseDto getCommunityBoardDetail(Long id); + List getAllCommunityBoards(); } diff --git a/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentService.java b/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentService.java new file mode 100644 index 000000000..f202b3423 --- /dev/null +++ b/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentService.java @@ -0,0 +1,34 @@ +package com.somemore.recruitboard.service.query; + +import com.somemore.recruitboard.domain.RecruitBoard; +import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; +import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; +import com.somemore.recruitboard.repository.RecruitBoardRepository; +import com.somemore.recruitboard.repository.mapper.RecruitBoardWithCenter; +import com.somemore.recruitboard.usecase.query.RecruitBoardDocumentUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@RequiredArgsConstructor +@Service +public class RecruitBoardDocumentService implements RecruitBoardDocumentUseCase { + + private final RecruitBoardRepository recruitBoardRepository; + + @Transactional(readOnly = true) + @Override + public Page getRecruitBoardBySearch(String keyword, RecruitBoardSearchCondition condition) { + Page boards = recruitBoardRepository.findByRecruitBoardsContaining(keyword, condition); + return boards.map(RecruitBoardWithCenterResponseDto::from); + } + + @Transactional + @Override + public void saveRecruitBoardDocuments(List recruitBoards) { + recruitBoardRepository.saveDocuments(recruitBoards); + } +} diff --git a/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardQueryService.java b/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardQueryService.java index c93420b09..f9f768395 100644 --- a/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardQueryService.java +++ b/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardQueryService.java @@ -86,4 +86,8 @@ public List getAllByIds(List ids) { return recruitBoardRepository.findAllByIds(ids); } + @Override + public List getAllRecruitBoards() { + return recruitBoardRepository.findAll(); + } } diff --git a/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardDocumentUseCase.java b/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardDocumentUseCase.java new file mode 100644 index 000000000..eb88b44c7 --- /dev/null +++ b/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardDocumentUseCase.java @@ -0,0 +1,13 @@ +package com.somemore.recruitboard.usecase.query; + +import com.somemore.recruitboard.domain.RecruitBoard; +import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; +import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; +import org.springframework.data.domain.Page; + +import java.util.List; + +public interface RecruitBoardDocumentUseCase { + Page getRecruitBoardBySearch(String keyword, RecruitBoardSearchCondition condition); + void saveRecruitBoardDocuments(List recruitBoards); +} diff --git a/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardQueryUseCase.java b/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardQueryUseCase.java index f940244b0..e355920db 100644 --- a/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardQueryUseCase.java +++ b/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardQueryUseCase.java @@ -30,4 +30,7 @@ Page getRecruitBoardsByCenterId(UUID centerId, List getNotCompletedIdsByCenterIds(UUID centerId); List getAllByIds(List ids); + + List getAllRecruitBoards(); + } From ea3d75b07d64e5aad8c767a0f223de71011be2ec Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 01:29:05 +0900 Subject: [PATCH 05/23] =?UTF-8?q?feature(search):=20controller=20=ED=82=A4?= =?UTF-8?q?=EC=9B=8C=EB=93=9C=20=EA=B2=80=EC=83=89=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommunityBoardQueryApiController.java | 15 +++++++++++++++ .../RecruitBoardQueryApiController.java | 4 +++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/somemore/community/controller/CommunityBoardQueryApiController.java b/src/main/java/com/somemore/community/controller/CommunityBoardQueryApiController.java index 18f112412..4af56163f 100644 --- a/src/main/java/com/somemore/community/controller/CommunityBoardQueryApiController.java +++ b/src/main/java/com/somemore/community/controller/CommunityBoardQueryApiController.java @@ -2,6 +2,7 @@ import com.somemore.community.dto.response.CommunityBoardDetailResponseDto; import com.somemore.community.dto.response.CommunityBoardResponseDto; +import com.somemore.community.usecase.board.CommunityBoardDocumentUseCase; import com.somemore.community.usecase.board.CommunityBoardQueryUseCase; import com.somemore.global.common.response.ApiResponse; import io.swagger.v3.oas.annotations.Operation; @@ -20,6 +21,7 @@ public class CommunityBoardQueryApiController { private final CommunityBoardQueryUseCase communityBoardQueryUseCase; + private final CommunityBoardDocumentUseCase communityBoardDocumentUseCase; @GetMapping("/community-boards") @Operation(summary = "전체 커뮤니티 게시글 조회", description = "전체 커뮤니티 게시글 목록을 조회합니다.") @@ -46,6 +48,19 @@ public ApiResponse> getByWriterId( ); } + @GetMapping("/community-boards/search") + @Operation(summary = "커뮤니티 게시글 키워드 검색", description = "키워드로 포함한 커뮤니티 게시글 목록을 조회합니다.") + public ApiResponse> getCommunityBoardsBySearch( + String keyword, + Pageable pageable + ) { + return ApiResponse.ok( + 200, + communityBoardDocumentUseCase.getCommunityBoardBySearch(keyword, pageable.getPageNumber()), + "커뮤니티 게시글 검색 리스트 조회 성공" + ); + } + @GetMapping("/community-board/{id}") @Operation(summary = "커뮤니티 게시글 상세 조회", description = "커뮤니티 게시글의 상세 정보를 조회합니다.") public ApiResponse getById( diff --git a/src/main/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiController.java b/src/main/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiController.java index 5465f066b..dfe7c26cc 100644 --- a/src/main/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiController.java +++ b/src/main/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiController.java @@ -11,6 +11,7 @@ import com.somemore.recruitboard.dto.response.RecruitBoardResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithLocationResponseDto; +import com.somemore.recruitboard.usecase.query.RecruitBoardDocumentUseCase; import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -32,6 +33,7 @@ public class RecruitBoardQueryApiController { private final RecruitBoardQueryUseCase recruitBoardQueryUseCase; + private final RecruitBoardDocumentUseCase recruitBoardDocumentUseCase; @GetMapping("/recruit-board/{id}") @Operation(summary = "봉사 모집글 상세 조회", description = "특정 모집글의 상세 정보를 조회합니다.") @@ -83,7 +85,7 @@ public ApiResponse> getAllBySearch( return ApiResponse.ok( 200, - recruitBoardQueryUseCase.getAllWithCenter(condition), + recruitBoardDocumentUseCase.getRecruitBoardBySearch(keyword, condition), "봉사 활동 모집글 검색 조회 성공" ); } From 53533f1e0364cdeffcee057d38bdfff1a439bfa6 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 01:29:26 +0900 Subject: [PATCH 06/23] =?UTF-8?q?feature(search):=20elasticsearch=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EC=8A=A4=EC=BC=80=EC=A5=B4=EB=9F=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/somemore/SomemoreApplication.java | 3 ++- .../scheduler/CommunityScheduler.java | 25 +++++++++++++++++++ .../scheduler/RecruitBoardScheduler.java | 25 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/somemore/community/scheduler/CommunityScheduler.java create mode 100644 src/main/java/com/somemore/recruitboard/scheduler/RecruitBoardScheduler.java diff --git a/src/main/java/com/somemore/SomemoreApplication.java b/src/main/java/com/somemore/SomemoreApplication.java index dec2413b5..076b1cca3 100644 --- a/src/main/java/com/somemore/SomemoreApplication.java +++ b/src/main/java/com/somemore/SomemoreApplication.java @@ -3,13 +3,14 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableJpaAuditing +@EnableScheduling public class SomemoreApplication { public static void main(String[] args) { SpringApplication.run(SomemoreApplication.class, args); } - } diff --git a/src/main/java/com/somemore/community/scheduler/CommunityScheduler.java b/src/main/java/com/somemore/community/scheduler/CommunityScheduler.java new file mode 100644 index 000000000..6eb624405 --- /dev/null +++ b/src/main/java/com/somemore/community/scheduler/CommunityScheduler.java @@ -0,0 +1,25 @@ +package com.somemore.community.scheduler; + +import com.somemore.community.domain.CommunityBoard; +import com.somemore.community.usecase.board.CommunityBoardDocumentUseCase; +import com.somemore.community.usecase.board.CommunityBoardQueryUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@RequiredArgsConstructor +public class CommunityScheduler { + + private final CommunityBoardQueryUseCase communityBoardQueryUseCase; + private final CommunityBoardDocumentUseCase communityBoardDocumentUseCase; + + + @Scheduled(cron = "10 * * * * *") + public void updateCommunityBoardDocuments() { + List communityBoards = communityBoardQueryUseCase.getAllCommunityBoards(); + communityBoardDocumentUseCase.saveCommunityBoardDocuments(communityBoards); + } +} diff --git a/src/main/java/com/somemore/recruitboard/scheduler/RecruitBoardScheduler.java b/src/main/java/com/somemore/recruitboard/scheduler/RecruitBoardScheduler.java new file mode 100644 index 000000000..41957a64c --- /dev/null +++ b/src/main/java/com/somemore/recruitboard/scheduler/RecruitBoardScheduler.java @@ -0,0 +1,25 @@ +package com.somemore.recruitboard.scheduler; + +import com.somemore.recruitboard.domain.RecruitBoard; +import com.somemore.recruitboard.repository.RecruitBoardRepository; +import com.somemore.recruitboard.usecase.query.RecruitBoardDocumentUseCase; +import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@RequiredArgsConstructor +public class RecruitBoardScheduler { + + private final RecruitBoardQueryUseCase recruitBoardQueryUseCase; + private final RecruitBoardDocumentUseCase recruitBoardDocumentUseCase; + + @Scheduled(cron = "10 * * * * *") + public void updateRecruitBoardDocuments() { + List recruitBoards = recruitBoardQueryUseCase.getAllRecruitBoards(); + recruitBoardDocumentUseCase.saveRecruitBoardDocuments(recruitBoards); + } +} From 27994bb457d4e426e7d3ae21f2534c77c37f5da4 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 01:30:53 +0900 Subject: [PATCH 07/23] =?UTF-8?q?feature(search):=20elasticsearch=20config?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/configure/ElasticsearchConfig.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/com/somemore/global/configure/ElasticsearchConfig.java diff --git a/src/main/java/com/somemore/global/configure/ElasticsearchConfig.java b/src/main/java/com/somemore/global/configure/ElasticsearchConfig.java new file mode 100644 index 000000000..e415fbe8c --- /dev/null +++ b/src/main/java/com/somemore/global/configure/ElasticsearchConfig.java @@ -0,0 +1,24 @@ +package com.somemore.global.configure; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.elasticsearch.client.ClientConfiguration; +import org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration; + +@Configuration +public class ElasticsearchConfig extends ElasticsearchConfiguration { + @Value("${elastic.search.uris}") + private String uri; + @Value("${elastic.search.username}") + private String username; + @Value("${elastic.search.password}") + private String password; + + @Override + public ClientConfiguration clientConfiguration() { + return ClientConfiguration.builder() + .connectedTo(uri) + .withBasicAuth(username, password) + .build(); + } +} From 0a99d885889e906aebbc39ac39fc673b0b6c9115 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 01:31:35 +0900 Subject: [PATCH 08/23] =?UTF-8?q?feature(search):=20community=20=EA=B2=8C?= =?UTF-8?q?=EC=8B=9C=EA=B8=80=20fixture=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../somemore/common/fixture/CommunityBoardFixture.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/test/java/com/somemore/common/fixture/CommunityBoardFixture.java b/src/test/java/com/somemore/common/fixture/CommunityBoardFixture.java index a55264dc7..4856e49a9 100644 --- a/src/test/java/com/somemore/common/fixture/CommunityBoardFixture.java +++ b/src/test/java/com/somemore/common/fixture/CommunityBoardFixture.java @@ -39,4 +39,12 @@ public static CommunityBoard createCommunityBoard(String title, UUID writerId) { .writerId(writerId) .build(); } + public static CommunityBoard createCommunityBoard(String title, String content, UUID writerId) { + return CommunityBoard.builder() + .title(title) + .content(content) + .imgUrl(IMG_URL) + .writerId(writerId) + .build(); + } } From aa4c16d5090e317b035bcc565b7490b7756bba56 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 01:32:22 +0900 Subject: [PATCH 09/23] =?UTF-8?q?test(search):=20community=20=EA=B2=8C?= =?UTF-8?q?=EC=8B=9C=EA=B8=80=20=EA=B2=80=EC=83=89=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommunityBoardQueryApiControllerTest.java | 27 ++++++++ .../CommunityBoardDocumentRepositoryTest.java | 63 +++++++++++++++++ .../CommunityBoardRepositoryTest.java | 30 ++++++++ .../CommunityBoardDocumentServiceTest.java | 68 +++++++++++++++++++ .../board/CommunityBoardQueryServiceTest.java | 29 ++++++++ 5 files changed, 217 insertions(+) create mode 100644 src/test/java/com/somemore/community/repository/CommunityBoardDocumentRepositoryTest.java create mode 100644 src/test/java/com/somemore/community/service/board/CommunityBoardDocumentServiceTest.java diff --git a/src/test/java/com/somemore/community/controller/CommunityBoardQueryApiControllerTest.java b/src/test/java/com/somemore/community/controller/CommunityBoardQueryApiControllerTest.java index 74e05b775..cf45a35a7 100644 --- a/src/test/java/com/somemore/community/controller/CommunityBoardQueryApiControllerTest.java +++ b/src/test/java/com/somemore/community/controller/CommunityBoardQueryApiControllerTest.java @@ -11,6 +11,7 @@ import com.somemore.ControllerTestSupport; import com.somemore.community.dto.response.CommunityBoardDetailResponseDto; import com.somemore.community.dto.response.CommunityBoardResponseDto; +import com.somemore.community.usecase.board.CommunityBoardDocumentUseCase; import com.somemore.community.usecase.board.CommunityBoardQueryUseCase; import java.util.Collections; import java.util.UUID; @@ -32,6 +33,9 @@ public class CommunityBoardQueryApiControllerTest extends ControllerTestSupport @MockBean private CommunityBoardQueryUseCase communityBoardQueryUseCase; + @MockBean + private CommunityBoardDocumentUseCase communityBoardDocumentUseCase; + @Test @DisplayName("커뮤니티 게시글 전체 조회 성공") void getAll() throws Exception { @@ -101,4 +105,27 @@ void getById() throws Exception { verify(communityBoardQueryUseCase, times(1)) .getCommunityBoardDetail(any()); } + + @Test + @DisplayName("커뮤니티 게시글 검색 조회 성공") + void getBySearch() throws Exception { + // given + Page page = new PageImpl<>(Collections.emptyList()); + + given(communityBoardDocumentUseCase.getCommunityBoardBySearch(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(communityBoardDocumentUseCase, times(1)).getCommunityBoardBySearch( + any(), anyInt()); + } } diff --git a/src/test/java/com/somemore/community/repository/CommunityBoardDocumentRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityBoardDocumentRepositoryTest.java new file mode 100644 index 000000000..8c17af2db --- /dev/null +++ b/src/test/java/com/somemore/community/repository/CommunityBoardDocumentRepositoryTest.java @@ -0,0 +1,63 @@ +package com.somemore.community.repository; + +import com.somemore.IntegrationTestSupport; +import com.somemore.auth.oauth.OAuthProvider; +import com.somemore.community.domain.CommunityBoard; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.community.repository.mapper.CommunityBoardView; +import com.somemore.volunteer.domain.Volunteer; +import com.somemore.volunteer.repository.VolunteerRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.transaction.annotation.Transactional; + + +import static com.somemore.common.fixture.CommunityBoardFixture.createCommunityBoard; +import static org.assertj.core.api.Assertions.assertThat; + +@Transactional +public class CommunityBoardDocumentRepositoryTest extends IntegrationTestSupport { + + @Autowired + private CommunityBoardRepository communityBoardRepository; + @Autowired + private VolunteerRepository volunteerRepository; + + @BeforeEach + void setUp() { + String oAuthId = "example-oauth-id2"; + Volunteer volunteer = Volunteer.createDefault(OAuthProvider.NAVER, oAuthId); + volunteerRepository.save(volunteer); + + for (int i = 1; i <= 20; i++) { + String title = "제목" + i; + CommunityBoard communityBoard = createCommunityBoard(title, volunteer.getId()); + communityBoardRepository.save(communityBoard); + } + } + + @DisplayName("검색 키워드가 포함된 게시글을 조회할 수 있다. (repository)") + @Test + void findByCommunityBoardsContaining() throws InterruptedException { + //given + Pageable pageable = getPageable(); + + //when + Page findBoards = communityBoardRepository.findByCommunityBoardsContaining("봉사", pageable); + + //then + assertThat(findBoards).isNotNull(); + assertThat(findBoards.getTotalElements()).isEqualTo(9); + assertThat(findBoards.getSize()).isEqualTo(10); + assertThat(findBoards.getTotalPages()).isEqualTo(1); + } + + private Pageable getPageable() { + return PageRequest.of(0, 10); + } +} diff --git a/src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java index 1d7202844..a4949fcd8 100644 --- a/src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java +++ b/src/test/java/com/somemore/community/repository/CommunityBoardRepositoryTest.java @@ -18,6 +18,8 @@ import static com.somemore.common.fixture.CommunityBoardFixture.createCommunityBoard; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import java.util.UUID; @@ -138,6 +140,34 @@ void existsById() { assertThat(isExist).isTrue(); } + @DisplayName("게시글을 elastic search index에 저장할 수 있다. (repository)") + @Test + void saveDocuments() { + //given + Pageable pageable = getPageable(); + + List communityBoards = new ArrayList<>(); + + CommunityBoard communityBoard1 = createCommunityBoard("저장 잘 되나요?", writerId); + CommunityBoard savedBoard1 = communityBoardRepository.save(communityBoard1); + CommunityBoard communityBoard2 = createCommunityBoard("잘 되나요?", "저장이요", writerId); + CommunityBoard savedBoard2 = communityBoardRepository.save(communityBoard2); + communityBoards.add(savedBoard1); + communityBoards.add(savedBoard2); + + //when + communityBoardRepository.saveDocuments(communityBoards); + + //then + Page findBoard = communityBoardRepository.findByCommunityBoardsContaining("저장", pageable); + + assertThat(findBoard).isNotNull(); + assertThat(findBoard.getTotalElements()).isEqualTo(2); + + communityBoardRepository.deleteDocument(savedBoard1.getId()); + communityBoardRepository.deleteDocument(savedBoard2.getId()); + } + private Pageable getPageable() { return PageRequest.of(0, 10); } diff --git a/src/test/java/com/somemore/community/service/board/CommunityBoardDocumentServiceTest.java b/src/test/java/com/somemore/community/service/board/CommunityBoardDocumentServiceTest.java new file mode 100644 index 000000000..49b7678e3 --- /dev/null +++ b/src/test/java/com/somemore/community/service/board/CommunityBoardDocumentServiceTest.java @@ -0,0 +1,68 @@ +package com.somemore.community.service.board; + +import com.somemore.IntegrationTestSupport; +import com.somemore.auth.oauth.OAuthProvider; +import com.somemore.community.domain.CommunityBoard; +import com.somemore.community.dto.response.CommunityBoardResponseDto; +import com.somemore.community.repository.board.CommunityBoardRepository; +import com.somemore.volunteer.domain.Volunteer; +import com.somemore.volunteer.repository.VolunteerRepository; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; + +import java.util.UUID; + +import static com.somemore.common.fixture.CommunityBoardFixture.createCommunityBoard; +import static org.assertj.core.api.Assertions.assertThat; + +public class CommunityBoardDocumentServiceTest extends IntegrationTestSupport { + + @Autowired + private CommunityBoardDocumentService communityBoardDocumentService; + + @Autowired + private CommunityBoardRepository communityBoardRepository; + + @Autowired + private VolunteerRepository volunteerRepository; + + private UUID writerId; + + @BeforeEach + void setUp() { + String oAuthId1 = "example-oauth-id1"; + Volunteer volunteer1 = Volunteer.createDefault(OAuthProvider.NAVER, oAuthId1); + volunteerRepository.save(volunteer1); + writerId = volunteer1.getId(); + + for (int i = 1; i <= 18; i++) { + String title = "제목" + i; + CommunityBoard communityBoard = createCommunityBoard(title, writerId); + communityBoardRepository.save(communityBoard); + } + } + + @AfterEach + void tearDown() { + communityBoardRepository.deleteAllInBatch(); + } + + @DisplayName("검색 키워드가 포함된 게시글을 조회한다. (service)") + @Test + void getCommunityBoardBySearch() { + //given + //when + Page dtos = communityBoardDocumentService.getCommunityBoardBySearch("봉사", 0); + + //then + assertThat(dtos).isNotNull(); + assertThat(dtos.getContent()).isNotNull(); + assertThat(dtos.getTotalElements()).isEqualTo(9); + assertThat(dtos.getSize()).isEqualTo(10); + assertThat(dtos.getTotalPages()).isEqualTo(1); + } +} diff --git a/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java b/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java index 44c05fe98..ac170f2a5 100644 --- a/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java @@ -21,6 +21,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @@ -43,6 +45,8 @@ class CommunityBoardQueryServiceTest extends IntegrationTestSupport { DeleteCommunityBoardUseCase deleteCommunityBoardUseCase; @Autowired CommunityBoardQueryService communityBoardQueryService; + @Autowired + private CommunityBoardDocumentService communityBoardDocumentService; private UUID writerId1; private Long communityId1; @@ -146,5 +150,30 @@ void getCommunityBoardDetailWithDeletedId() { .isThrownBy(callable) .withMessage(ExceptionMessage.NOT_EXISTS_COMMUNITY_BOARD.getMessage()); } + + @DisplayName("게시글을 elastic search index에 저장한다. (service)") + @Test + void saveCommunityBoardDocuments() { + //given + List communityBoards = new ArrayList<>(); + + CommunityBoard communityBoard = createCommunityBoard("저장 잘 되나요?", "안녕하세요", UUID.randomUUID()); + CommunityBoard savedBoard = communityBoardRepository.save(communityBoard); + communityBoards.add(savedBoard); + + //when + communityBoardDocumentService.saveCommunityBoardDocuments(communityBoards); + + //then + Page dtos = communityBoardDocumentService.getCommunityBoardBySearch("저장", 0); + + assertThat(dtos).isNotNull(); + assertThat(dtos.getContent()).isNotNull(); + assertThat(dtos.getTotalElements()).isEqualTo(1); + assertThat(dtos.getSize()).isEqualTo(10); + assertThat(dtos.getTotalPages()).isEqualTo(1); + + communityBoardRepository.deleteDocument(savedBoard.getId()); + } } From 4d59d93d96a0e9766039f9a343f7821f804e1c24 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 01:32:54 +0900 Subject: [PATCH 10/23] =?UTF-8?q?test(search):=20recruit=20=EB=AA=A8?= =?UTF-8?q?=EC=A7=91=EA=B8=80=20=EA=B2=80=EC=83=89=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecruitBoardQueryApiControllerTest.java | 10 ++- .../RecruitBoardDocumentRepositoryTest.java | 82 +++++++++++++++++ .../RecruitBoardRepositoryImplTest.java | 34 ++++++++ .../RecruitBoardDocumentServiceTest.java | 87 +++++++++++++++++++ .../query/RecruitBoardQueryServiceTest.java | 39 +++++++++ 5 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java create mode 100644 src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java diff --git a/src/test/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiControllerTest.java b/src/test/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiControllerTest.java index 5a48b9775..be12ad1a1 100644 --- a/src/test/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiControllerTest.java +++ b/src/test/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiControllerTest.java @@ -17,6 +17,7 @@ import com.somemore.recruitboard.dto.response.RecruitBoardResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithLocationResponseDto; +import com.somemore.recruitboard.usecase.query.RecruitBoardDocumentUseCase; import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; import java.util.Collections; import java.util.UUID; @@ -37,6 +38,9 @@ class RecruitBoardQueryApiControllerTest extends ControllerTestSupport { @MockBean private RecruitBoardQueryUseCase recruitBoardQueryUseCase; + @MockBean + private RecruitBoardDocumentUseCase documentUseCase; + @Test @DisplayName("모집글 ID로 상세 조회할 수 있다.") void getById() throws Exception { @@ -85,7 +89,7 @@ void getAllBySearch() throws Exception { // given Page page = new PageImpl<>(Collections.emptyList()); - given(recruitBoardQueryUseCase.getAllWithCenter(any(RecruitBoardSearchCondition.class))) + given(documentUseCase.getRecruitBoardBySearch(any(), any(RecruitBoardSearchCondition.class))) .willReturn(page); // when @@ -99,8 +103,8 @@ void getAllBySearch() throws Exception { .andExpect(jsonPath("$.data").exists()) .andExpect(jsonPath("$.message").value("봉사 활동 모집글 검색 조회 성공")); - verify(recruitBoardQueryUseCase, times(1)).getAllWithCenter( - any(RecruitBoardSearchCondition.class)); + verify(documentUseCase, times(1)).getRecruitBoardBySearch( + any(), any(RecruitBoardSearchCondition.class)); } @Test diff --git a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java new file mode 100644 index 000000000..7f39130f8 --- /dev/null +++ b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java @@ -0,0 +1,82 @@ +package com.somemore.recruitboard.repository; + +import com.somemore.IntegrationTestSupport; +import com.somemore.center.domain.Center; +import com.somemore.center.repository.CenterRepository; +import com.somemore.location.domain.Location; +import com.somemore.location.repository.LocationRepository; +import com.somemore.recruitboard.domain.RecruitBoard; +import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; +import com.somemore.recruitboard.repository.mapper.RecruitBoardWithCenter; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +import static com.somemore.common.fixture.CenterFixture.createCenter; +import static com.somemore.common.fixture.LocationFixture.createLocation; +import static com.somemore.common.fixture.RecruitBoardFixture.createRecruitBoard; +import static org.assertj.core.api.Assertions.assertThat; + +@Transactional +public class RecruitBoardDocumentRepositoryTest extends IntegrationTestSupport { + + @Autowired + private RecruitBoardRepository recruitBoardRepository; + + @Autowired + private LocationRepository locationRepository; + + @Autowired + private CenterRepository centerRepository; + + private final List boards = new ArrayList<>(); + + @BeforeEach + void setUp() { + Location location = createLocation(); + locationRepository.save(location); + + Center center = createCenter(); + centerRepository.save(center); + + for (int i = 1; i <= 30; i++) { + String title = "제목" + i; + RecruitBoard board = createRecruitBoard(title, center.getId(), location.getId()); + boards.add(board); + } + recruitBoardRepository.saveAll(boards); + } + + @DisplayName("검색 키워드가 포함된 모집글을 조회할 수 있다.") + @Test + void findByRecruitBoardsContaining() { + //given + Pageable pageable = getPageable(); + RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() + .pageable(pageable) + .build(); + + //when + Page findBoards = recruitBoardRepository.findByRecruitBoardsContaining("없음", condition); + + //then + assertThat(findBoards).isNotNull(); + assertThat(findBoards.getTotalElements()).isEqualTo(4); + assertThat(findBoards.getSize()).isEqualTo(5); + assertThat(findBoards.getTotalPages()).isEqualTo(1); + } + + private Pageable getPageable() { + Sort sort = Sort.by(Sort.Order.desc("created_at")); + return PageRequest.of(0, 5, sort); + } +} diff --git a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImplTest.java b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImplTest.java index 1b0268c59..b753c9fe8 100644 --- a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImplTest.java +++ b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImplTest.java @@ -51,6 +51,8 @@ class RecruitBoardRepositoryImplTest extends IntegrationTestSupport { private final List boards = new ArrayList<>(); + private UUID centerId; + @BeforeEach void setUp() { Location location = createLocation(); @@ -58,6 +60,7 @@ void setUp() { Center center = createCenter(); centerRepository.save(center); + centerId = center.getId(); for (int i = 1; i <= 100; i++) { String title = "제목" + i; @@ -426,6 +429,37 @@ void findAllByIds() { assertThat(all).hasSize(3); } + @DisplayName("모집글을 elastic search index에 저장할 수 있다. (repository)") + @Test + void saveDocuments() { + //given + Pageable pageable = getPageable(); + RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() + .pageable(pageable) + .build(); + + List recruitBoards = new ArrayList<>(); + + RecruitBoard board1 = createRecruitBoard("저장 잘 되나요?", centerId); + RecruitBoard savedBoard1 = recruitBoardRepository.save(board1); + RecruitBoard board2 = createRecruitBoard("저장해줘", centerId); + RecruitBoard savedBoard2 = recruitBoardRepository.save(board2); + recruitBoards.add(savedBoard1); + recruitBoards.add(savedBoard2); + + //when + recruitBoardRepository.saveDocuments(recruitBoards); + + //then + Page findBoard = recruitBoardRepository.findByRecruitBoardsContaining("저장", condition); + + assertThat(findBoard).isNotNull(); + assertThat(findBoard.getTotalElements()).isEqualTo(2); + + recruitBoardRepository.deleteDocument(savedBoard1.getId()); + recruitBoardRepository.deleteDocument(savedBoard2.getId()); + } + private Pageable getPageable() { Sort sort = Sort.by(Sort.Order.desc("created_at")); return PageRequest.of(0, 5, sort); diff --git a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java new file mode 100644 index 000000000..91499f8a4 --- /dev/null +++ b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java @@ -0,0 +1,87 @@ +package com.somemore.recruitboard.service.query; + +import com.somemore.IntegrationTestSupport; +import com.somemore.center.domain.Center; +import com.somemore.center.repository.CenterRepository; +import com.somemore.location.domain.Location; +import com.somemore.location.repository.LocationRepository; +import com.somemore.recruitboard.domain.RecruitBoard; +import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; +import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; +import com.somemore.recruitboard.repository.RecruitBoardRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +import static com.somemore.common.fixture.CenterFixture.createCenter; +import static com.somemore.common.fixture.LocationFixture.createLocation; +import static com.somemore.common.fixture.RecruitBoardFixture.createRecruitBoard; +import static org.assertj.core.api.Assertions.assertThat; + +@Transactional +public class RecruitBoardDocumentServiceTest extends IntegrationTestSupport { + + @Autowired + private RecruitBoardDocumentService recruitBoardDocumentService; + + @Autowired + private RecruitBoardRepository recruitBoardRepository; + + @Autowired + private LocationRepository locationRepository; + + @Autowired + private CenterRepository centerRepository; + + private final List boards = new ArrayList<>(); + + @BeforeEach + public void setUp() { + Location location = createLocation(); + locationRepository.save(location); + + Center center = createCenter(); + centerRepository.save(center); + + for (int i = 1; i <= 30; i++) { + String title = "제목" + i; + RecruitBoard board = createRecruitBoard(title, center.getId(), location.getId()); + boards.add(board); + } + recruitBoardRepository.saveAll(boards); + } + + @DisplayName("검색 키워드가 포함된 모집글을 조회한다. (service)") + @Test + void getRecruitBoardBySearch() { + //given + Pageable pageable = getPageable(); + RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() + .pageable(pageable) + .build(); + + //when + Page dtos = recruitBoardDocumentService.getRecruitBoardBySearch("노인", condition); + + //then + assertThat(dtos).isNotNull(); + assertThat(dtos.getContent()).isNotNull(); + assertThat(dtos.getTotalElements()).isEqualTo(4); + assertThat(dtos.getSize()).isEqualTo(5); + assertThat(dtos.getTotalPages()).isEqualTo(1); + } + + private Pageable getPageable() { + Sort sort = Sort.by(Sort.Order.desc("created_at")); + return PageRequest.of(0, 5, sort); + } +} diff --git a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardQueryServiceTest.java b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardQueryServiceTest.java index 7cdcc6b2c..533ef93e3 100644 --- a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardQueryServiceTest.java +++ b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardQueryServiceTest.java @@ -25,6 +25,8 @@ import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithLocationResponseDto; import com.somemore.recruitboard.repository.RecruitBoardRepository; + +import java.util.ArrayList; import java.util.List; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; @@ -43,6 +45,9 @@ class RecruitBoardQueryServiceTest extends IntegrationTestSupport { @Autowired private RecruitBoardQueryService recruitBoardQueryService; + @Autowired + private RecruitBoardDocumentService recruitBoardDocumentService; + @Autowired private RecruitBoardRepository recruitBoardRepository; @@ -280,6 +285,40 @@ void getAllByIds() { assertThat(all).hasSize(3); } + @DisplayName("모집글을 elastic search index에 저장한다. (service)") + @Test + void saveRecruitBoardDocuments() { + //given + Center center = createCenter("특별한 기관"); + centerRepository.save(center); + + Pageable pageable = getPageable(); + RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() + .pageable(pageable) + .build(); + + List recruitBoards = new ArrayList<>(); + + RecruitBoard board1 = createRecruitBoard("저장 잘 되나요?", center.getId()); + RecruitBoard savedBoard1 = recruitBoardRepository.save(board1); + RecruitBoard board2 = createRecruitBoard("저장해줘", center.getId()); + RecruitBoard savedBoard2 = recruitBoardRepository.save(board2); + recruitBoards.add(savedBoard1); + recruitBoards.add(savedBoard2); + + //when + recruitBoardDocumentService.saveRecruitBoardDocuments(recruitBoards); + + //then + Page findBoard = recruitBoardDocumentService.getRecruitBoardBySearch("저장", condition); + + assertThat(findBoard).isNotNull(); + assertThat(findBoard.getTotalElements()).isEqualTo(2); + + recruitBoardRepository.deleteDocument(savedBoard1.getId()); + recruitBoardRepository.deleteDocument(savedBoard2.getId()); + } + private Pageable getPageable() { Sort sort = Sort.by(Sort.Order.desc("created_at")); return PageRequest.of(0, 5, sort); From 3fa8e8edcaf63e2e49f519028da2eb2d276623bd Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 01:41:47 +0900 Subject: [PATCH 11/23] =?UTF-8?q?test(search):=20import=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/RecruitBoardDocumentRepositoryTest.java | 2 +- .../service/query/RecruitBoardDocumentServiceTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java index 7f39130f8..a9d508503 100644 --- a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java +++ b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java @@ -2,7 +2,7 @@ import com.somemore.IntegrationTestSupport; import com.somemore.center.domain.Center; -import com.somemore.center.repository.CenterRepository; +import com.somemore.center.repository.center.CenterRepository; import com.somemore.location.domain.Location; import com.somemore.location.repository.LocationRepository; import com.somemore.recruitboard.domain.RecruitBoard; diff --git a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java index 91499f8a4..2112381b5 100644 --- a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java +++ b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java @@ -2,7 +2,7 @@ import com.somemore.IntegrationTestSupport; import com.somemore.center.domain.Center; -import com.somemore.center.repository.CenterRepository; +import com.somemore.center.repository.center.CenterRepository; import com.somemore.location.domain.Location; import com.somemore.location.repository.LocationRepository; import com.somemore.recruitboard.domain.RecruitBoard; From f1fc7d65a413dd275c1dd9f0e39b323fbcb00b45 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 01:53:10 +0900 Subject: [PATCH 12/23] =?UTF-8?q?refactor(search):=20scheduler=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/somemore/community/scheduler/CommunityScheduler.java | 2 +- .../somemore/recruitboard/scheduler/RecruitBoardScheduler.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/somemore/community/scheduler/CommunityScheduler.java b/src/main/java/com/somemore/community/scheduler/CommunityScheduler.java index 6eb624405..8bfcc3aac 100644 --- a/src/main/java/com/somemore/community/scheduler/CommunityScheduler.java +++ b/src/main/java/com/somemore/community/scheduler/CommunityScheduler.java @@ -17,7 +17,7 @@ public class CommunityScheduler { private final CommunityBoardDocumentUseCase communityBoardDocumentUseCase; - @Scheduled(cron = "10 * * * * *") + @Scheduled(cron = "0 0 0 * * *") public void updateCommunityBoardDocuments() { List communityBoards = communityBoardQueryUseCase.getAllCommunityBoards(); communityBoardDocumentUseCase.saveCommunityBoardDocuments(communityBoards); diff --git a/src/main/java/com/somemore/recruitboard/scheduler/RecruitBoardScheduler.java b/src/main/java/com/somemore/recruitboard/scheduler/RecruitBoardScheduler.java index 41957a64c..8f55bac71 100644 --- a/src/main/java/com/somemore/recruitboard/scheduler/RecruitBoardScheduler.java +++ b/src/main/java/com/somemore/recruitboard/scheduler/RecruitBoardScheduler.java @@ -17,7 +17,7 @@ public class RecruitBoardScheduler { private final RecruitBoardQueryUseCase recruitBoardQueryUseCase; private final RecruitBoardDocumentUseCase recruitBoardDocumentUseCase; - @Scheduled(cron = "10 * * * * *") + @Scheduled(cron = "0 0 0 * * *") public void updateRecruitBoardDocuments() { List recruitBoards = recruitBoardQueryUseCase.getAllRecruitBoards(); recruitBoardDocumentUseCase.saveRecruitBoardDocuments(recruitBoards); From 8cb0b021672eba9a64969a143e9fa95e94e85aca Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 02:21:20 +0900 Subject: [PATCH 13/23] =?UTF-8?q?test(search):=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - application-test.yml 수정 - elastic search uris -> uri test(search): 코드 리뷰 사항 반영 - application-test.yml 수정 --- .../com/somemore/global/configure/ElasticsearchConfig.java | 2 +- src/main/resources/application.yml | 2 +- src/test/resources/application-test.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/somemore/global/configure/ElasticsearchConfig.java b/src/main/java/com/somemore/global/configure/ElasticsearchConfig.java index e415fbe8c..0a47d6c36 100644 --- a/src/main/java/com/somemore/global/configure/ElasticsearchConfig.java +++ b/src/main/java/com/somemore/global/configure/ElasticsearchConfig.java @@ -7,7 +7,7 @@ @Configuration public class ElasticsearchConfig extends ElasticsearchConfiguration { - @Value("${elastic.search.uris}") + @Value("${elastic.search.uri}") private String uri; @Value("${elastic.search.username}") private String username; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9c220f2e5..8e0844759 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -112,7 +112,7 @@ default: elastic: search: - uris: ${ELASTIC_URI} + uri: ${ELASTIC_URI} username: ${ELASTIC_USERNAME} password: ${ELASTIC_PASSWORD} diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml index 00940b63f..0128fe6c3 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application-test.yml @@ -60,7 +60,7 @@ cloud: static: ap-northeast-2 s3: bucket: somemore - base-url: https://somemore-images.s3.ap-northeast-2.amazonaws.com/ + base-url: https://somemore-image.s3.ap-northeast-2.amazonaws.com stack: auto: false @@ -70,7 +70,7 @@ default: elastic: search: - uris: localhost:9200 + uri: localhost:9200 username: elastic password: somemore From ffd2769c2d1bb1553208752c9b74fdbab311d613 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 04:42:50 +0900 Subject: [PATCH 14/23] =?UTF-8?q?feature(search):=20=EA=B2=80=EC=83=89=20k?= =?UTF-8?q?eyword=EA=B0=80=20null=EC=9D=B8=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommunityBoardDocumentRepository.java | 1 + .../board/CommunityBoardRepositoryImpl.java | 13 +++++++-- .../RecruitBoardDocumentRepository.java | 1 + .../RecruitBoardRepositoryImpl.java | 29 +++++++++++++++---- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/somemore/community/repository/board/CommunityBoardDocumentRepository.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardDocumentRepository.java index 41241b1c1..422a79697 100644 --- a/src/main/java/com/somemore/community/repository/board/CommunityBoardDocumentRepository.java +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardDocumentRepository.java @@ -7,6 +7,7 @@ import java.util.List; public interface CommunityBoardDocumentRepository extends ElasticsearchRepository { + List findAll(); @Query("{\"multi_match\": {\"query\": \"?0\", \"fields\": [\"title\", \"content\"]}}") List findIdsByTitleOrContentContaining(String keyword); } diff --git a/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java index 48ccccb1d..cbd96e99d 100644 --- a/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java +++ b/src/main/java/com/somemore/community/repository/board/CommunityBoardRepositoryImpl.java @@ -88,7 +88,7 @@ public boolean existsById(Long id) { @Override public Page findByCommunityBoardsContaining(String keyword, Pageable pageable) { - List boardDocuments = documentRepository.findIdsByTitleOrContentContaining(keyword); + List boardDocuments = getBoardDocuments(keyword); List boardIds = boardDocuments.stream() .map(CommunityBoardDocument::getId) @@ -105,7 +105,8 @@ public Page findByCommunityBoardsContaining(String keyword, .select(communityBoard.count()) .from(communityBoard) .join(volunteer).on(communityBoard.writerId.eq(volunteer.id)) - .where(communityBoard.id.in(boardIds)); + .where(communityBoard.id.in(boardIds) + .and(isNotDeleted())); return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchOne); } @@ -160,4 +161,12 @@ private BooleanExpression isNotDeleted() { } private BooleanExpression isWriter(UUID writerId) {return communityBoard.writerId.eq(writerId); } + + private List getBoardDocuments(String keyword) { + + if (keyword == null || keyword.isEmpty()) { + return documentRepository.findAll(); + } + return documentRepository.findIdsByTitleOrContentContaining(keyword); + } } diff --git a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepository.java b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepository.java index aaa0fe9b6..25017b8b9 100644 --- a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepository.java +++ b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepository.java @@ -7,6 +7,7 @@ import java.util.List; public interface RecruitBoardDocumentRepository extends ElasticsearchRepository { + List findAll(); @Query("{\"multi_match\": {\"query\": \"?0\", \"fields\": [\"title\", \"content\"]}}") List findIdsByTitleOrContentContaining(String keyword); } diff --git a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImpl.java b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImpl.java index 496c23124..0dc01c902 100644 --- a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImpl.java +++ b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImpl.java @@ -138,10 +138,15 @@ public Page findAllNearby(RecruitBoardNearByCondition condit QLocation location = QLocation.location; QCenter center = QCenter.center; + List boardDocuments = getBoardDocuments(condition.keyword()); + + List boardIds = boardDocuments.stream() + .map(RecruitBoardDocument::getId) + .toList(); + Pageable pageable = condition.pageable(); BooleanExpression predicate = locationBetween(condition) - .and(keywordEq(condition.keyword())) .and(statusEq(condition.status())) .and(isNotDeleted()); @@ -150,7 +155,8 @@ public Page findAllNearby(RecruitBoardNearByCondition condit .from(recruitBoard) .join(location).on(recruitBoard.locationId.eq(location.id)) .join(center).on(recruitBoard.centerId.eq(center.id)) - .where(predicate) + .where(recruitBoard.id.in(boardIds) + .and(predicate)) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .orderBy(toOrderSpecifiers(pageable.getSort())) @@ -161,7 +167,8 @@ public Page findAllNearby(RecruitBoardNearByCondition condit .from(recruitBoard) .join(location).on(recruitBoard.locationId.eq(location.id)) .join(center).on(recruitBoard.centerId.eq(center.id)) - .where(predicate); + .where(recruitBoard.id.in(boardIds) + .and(predicate)); return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchOne); } @@ -197,11 +204,12 @@ public Page findAllByCenterId(UUID centerId, } @Override - public Page findByRecruitBoardsContaining(String keyword, RecruitBoardSearchCondition condition) { + public Page findByRecruitBoardsContaining(RecruitBoardSearchCondition condition) { QRecruitBoard recruitBoard = QRecruitBoard.recruitBoard; QCenter center = QCenter.center; - List boardDocuments = documentRepository.findIdsByTitleOrContentContaining(keyword); + + List boardDocuments = getBoardDocuments(condition.keyword()); List boardIds = boardDocuments.stream() .map(RecruitBoardDocument::getId) @@ -229,7 +237,8 @@ public Page findByRecruitBoardsContaining(String keyword .select(recruitBoard.count()) .from(recruitBoard) .join(center).on(recruitBoard.centerId.eq(center.id)) - .where(predicate); + .where(recruitBoard.id.in(boardIds) + .and(predicate)); return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchOne); } @@ -361,4 +370,12 @@ private List convertEntityToDocuments(List r } return communityBoardDocuments; } + + private List getBoardDocuments(String keyword) { + + if (keyword == null || keyword.isEmpty()) { + return documentRepository.findAll(); + } + return documentRepository.findIdsByTitleOrContentContaining(keyword); + } } From 102b9e2c97f65b1b497562bf4c3da8e6ba6a409d Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 04:44:18 +0900 Subject: [PATCH 15/23] =?UTF-8?q?feature(search):=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=20=EA=B2=80=EC=83=89=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=ED=82=A4=EC=9B=8C=EB=93=9C=20condition=EC=97=90=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/RecruitBoardQueryApiController.java | 2 +- .../recruitboard/repository/RecruitBoardRepository.java | 2 +- .../service/query/RecruitBoardDocumentService.java | 4 ++-- .../usecase/query/RecruitBoardDocumentUseCase.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiController.java b/src/main/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiController.java index dfe7c26cc..b0e56a87a 100644 --- a/src/main/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiController.java +++ b/src/main/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiController.java @@ -85,7 +85,7 @@ public ApiResponse> getAllBySearch( return ApiResponse.ok( 200, - recruitBoardDocumentUseCase.getRecruitBoardBySearch(keyword, condition), + recruitBoardDocumentUseCase.getRecruitBoardBySearch(condition), "봉사 활동 모집글 검색 조회 성공" ); } diff --git a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepository.java b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepository.java index b4b34c9f0..f5c45582a 100644 --- a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepository.java +++ b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepository.java @@ -31,7 +31,7 @@ public interface RecruitBoardRepository { List findAllByIds(List ids); - Page findByRecruitBoardsContaining(String keyword, RecruitBoardSearchCondition condition); + Page findByRecruitBoardsContaining(RecruitBoardSearchCondition condition); void saveDocuments(List recruitBoards); List findAll(); void deleteDocument(Long id); diff --git a/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentService.java b/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentService.java index f202b3423..65b4da2df 100644 --- a/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentService.java +++ b/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentService.java @@ -21,8 +21,8 @@ public class RecruitBoardDocumentService implements RecruitBoardDocumentUseCase @Transactional(readOnly = true) @Override - public Page getRecruitBoardBySearch(String keyword, RecruitBoardSearchCondition condition) { - Page boards = recruitBoardRepository.findByRecruitBoardsContaining(keyword, condition); + public Page getRecruitBoardBySearch(RecruitBoardSearchCondition condition) { + Page boards = recruitBoardRepository.findByRecruitBoardsContaining(condition); return boards.map(RecruitBoardWithCenterResponseDto::from); } diff --git a/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardDocumentUseCase.java b/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardDocumentUseCase.java index eb88b44c7..17346186f 100644 --- a/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardDocumentUseCase.java +++ b/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardDocumentUseCase.java @@ -8,6 +8,6 @@ import java.util.List; public interface RecruitBoardDocumentUseCase { - Page getRecruitBoardBySearch(String keyword, RecruitBoardSearchCondition condition); + Page getRecruitBoardBySearch(RecruitBoardSearchCondition condition); void saveRecruitBoardDocuments(List recruitBoards); } From b78814c4f81efa7135ff04d9dd525da27e44691e Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 04:44:51 +0900 Subject: [PATCH 16/23] =?UTF-8?q?test(search):=20=EC=BB=A4=EB=AE=A4?= =?UTF-8?q?=EB=8B=88=ED=8B=B0=20=EA=B2=80=EC=83=89=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommunityBoardDocumentRepositoryTest.java | 18 +++++++++++++++++- .../CommunityBoardDocumentServiceTest.java | 15 +++++++++++++++ .../board/CommunityBoardQueryServiceTest.java | 6 +++--- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/somemore/community/repository/CommunityBoardDocumentRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityBoardDocumentRepositoryTest.java index 8c17af2db..d0f91356f 100644 --- a/src/test/java/com/somemore/community/repository/CommunityBoardDocumentRepositoryTest.java +++ b/src/test/java/com/somemore/community/repository/CommunityBoardDocumentRepositoryTest.java @@ -43,7 +43,7 @@ void setUp() { @DisplayName("검색 키워드가 포함된 게시글을 조회할 수 있다. (repository)") @Test - void findByCommunityBoardsContaining() throws InterruptedException { + void findByCommunityBoardsContaining() { //given Pageable pageable = getPageable(); @@ -57,6 +57,22 @@ void findByCommunityBoardsContaining() throws InterruptedException { assertThat(findBoards.getTotalPages()).isEqualTo(1); } +// @DisplayName("키워드 없이 검색시 전체 게시글을 조회할 수 있다. (repository)") +// @Test +// void findByCommunityBoardsContainingWithNull() { +// //given +// Pageable pageable = getPageable(); +// +// //when +// Page findBoards = communityBoardRepository.findByCommunityBoardsContaining(null, pageable); +// +// //then +// assertThat(findBoards).isNotNull(); +// assertThat(findBoards.getTotalElements()).isEqualTo(16); +// assertThat(findBoards.getSize()).isEqualTo(10); +// assertThat(findBoards.getTotalPages()).isEqualTo(2); +// } + private Pageable getPageable() { return PageRequest.of(0, 10); } diff --git a/src/test/java/com/somemore/community/service/board/CommunityBoardDocumentServiceTest.java b/src/test/java/com/somemore/community/service/board/CommunityBoardDocumentServiceTest.java index 49b7678e3..8657f9088 100644 --- a/src/test/java/com/somemore/community/service/board/CommunityBoardDocumentServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/CommunityBoardDocumentServiceTest.java @@ -65,4 +65,19 @@ void getCommunityBoardBySearch() { assertThat(dtos.getSize()).isEqualTo(10); assertThat(dtos.getTotalPages()).isEqualTo(1); } + +// @DisplayName("검색 키워드 없이 조회시 전체 게시글을 조회한다. (service)") +// @Test +// void getCommunityBoardBySearchWithNull() { +// //given +// //when +// Page dtos = communityBoardDocumentService.getCommunityBoardBySearch("", 0); +// +// //then +// assertThat(dtos).isNotNull(); +// assertThat(dtos.getContent()).isNotNull(); +// assertThat(dtos.getTotalElements()).isEqualTo(15); +// assertThat(dtos.getSize()).isEqualTo(10); +// assertThat(dtos.getTotalPages()).isEqualTo(2); +// } } diff --git a/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java b/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java index ac170f2a5..d0caba76d 100644 --- a/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java @@ -165,13 +165,13 @@ void saveCommunityBoardDocuments() { communityBoardDocumentService.saveCommunityBoardDocuments(communityBoards); //then - Page dtos = communityBoardDocumentService.getCommunityBoardBySearch("저장", 0); + Page dtos = communityBoardDocumentService.getCommunityBoardBySearch("", 0); assertThat(dtos).isNotNull(); assertThat(dtos.getContent()).isNotNull(); - assertThat(dtos.getTotalElements()).isEqualTo(1); + assertThat(dtos.getTotalElements()).isEqualTo(15); assertThat(dtos.getSize()).isEqualTo(10); - assertThat(dtos.getTotalPages()).isEqualTo(1); + assertThat(dtos.getTotalPages()).isEqualTo(2); communityBoardRepository.deleteDocument(savedBoard.getId()); } From 78990d0758762df53a5d505a83173517e1fb336a Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 04:45:02 +0900 Subject: [PATCH 17/23] =?UTF-8?q?test(search):=20=EB=B4=89=EC=82=AC?= =?UTF-8?q?=ED=99=9C=EB=8F=99=20=EB=AA=A8=EC=A7=91=EA=B8=80=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecruitBoardQueryApiControllerTest.java | 5 +- .../RecruitBoardDocumentRepositoryTest.java | 23 ++++- .../RecruitBoardRepositoryImplTest.java | 91 ++++++++++++++----- .../RecruitBoardDocumentServiceTest.java | 52 ++++++++++- .../query/RecruitBoardQueryServiceTest.java | 33 +------ 5 files changed, 146 insertions(+), 58 deletions(-) diff --git a/src/test/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiControllerTest.java b/src/test/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiControllerTest.java index be12ad1a1..3efcff89f 100644 --- a/src/test/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiControllerTest.java +++ b/src/test/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiControllerTest.java @@ -89,7 +89,7 @@ void getAllBySearch() throws Exception { // given Page page = new PageImpl<>(Collections.emptyList()); - given(documentUseCase.getRecruitBoardBySearch(any(), any(RecruitBoardSearchCondition.class))) + given(documentUseCase.getRecruitBoardBySearch(any(RecruitBoardSearchCondition.class))) .willReturn(page); // when @@ -103,8 +103,7 @@ void getAllBySearch() throws Exception { .andExpect(jsonPath("$.data").exists()) .andExpect(jsonPath("$.message").value("봉사 활동 모집글 검색 조회 성공")); - verify(documentUseCase, times(1)).getRecruitBoardBySearch( - any(), any(RecruitBoardSearchCondition.class)); + verify(documentUseCase, times(1)).getRecruitBoardBySearch(any(RecruitBoardSearchCondition.class)); } @Test diff --git a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java index a9d508503..9976ab006 100644 --- a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java +++ b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java @@ -62,11 +62,12 @@ void findByRecruitBoardsContaining() { //given Pageable pageable = getPageable(); RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() + .keyword("노인") .pageable(pageable) .build(); //when - Page findBoards = recruitBoardRepository.findByRecruitBoardsContaining("없음", condition); + Page findBoards = recruitBoardRepository.findByRecruitBoardsContaining(condition); //then assertThat(findBoards).isNotNull(); @@ -75,6 +76,26 @@ void findByRecruitBoardsContaining() { assertThat(findBoards.getTotalPages()).isEqualTo(1); } +// @DisplayName("키워드 없이 검색시 전체 모집글을 조회할 수 있다.") +// @Test +// void findByRecruitBoardsContainingWithNull() { +// //given +// Pageable pageable = getPageable(); +// RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() +// .keyword("") +// .pageable(pageable) +// .build(); +// +// //when +// Page findBoards = recruitBoardRepository.findByRecruitBoardsContaining(condition); +// +// //then +// assertThat(findBoards).isNotNull(); +// assertThat(findBoards.getTotalElements()).isEqualTo(23); +// assertThat(findBoards.getSize()).isEqualTo(5); +// assertThat(findBoards.getTotalPages()).isEqualTo(5); +// } + private Pageable getPageable() { Sort sort = Sort.by(Sort.Order.desc("created_at")); return PageRequest.of(0, 5, sort); diff --git a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImplTest.java b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImplTest.java index b753c9fe8..60329a848 100644 --- a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImplTest.java +++ b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImplTest.java @@ -323,27 +323,28 @@ void findAllWithCenterByStatus() { status); } - @DisplayName("위치 기반으로 반경 내에 모집글을 반환한다") - @Test - void findAllNearByLocation() { - // given - Pageable pageable = getPageable(); - - RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() - .latitude(37.5935) - .longitude(126.9780) - .radius(5.0) - .pageable(pageable) - .build(); - - // when - Page result = recruitBoardRepository.findAllNearby(condition); - - // then - assertThat(result).isNotNull(); - assertThat(result.getTotalElements()).isEqualTo(boards.size()); - assertThat(result.getContent()).isNotEmpty(); - } +// @DisplayName("위치 기반으로 반경 내에 모집글을 반환한다") +// @Test +// void findAllNearByLocation() { +// // given +// Pageable pageable = getPageable(); +// +// RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() +// .keyword(null) +// .latitude(37.5935) +// .longitude(126.9780) +// .radius(5.0) +// .pageable(pageable) +// .build(); +// +// // when +// Page result = recruitBoardRepository.findAllNearby(condition); +// +// // then +// assertThat(result).isNotNull(); +// assertThat(result.getTotalElements()).isEqualTo(28); +// assertThat(result.getContent()).isNotEmpty(); +// } @DisplayName("위치 기반으로 반경 내에 모집글이 없으면 빈 페이지를 반환한다") @Test @@ -352,6 +353,7 @@ void findAllNearByLocation_noResult() { Pageable pageable = getPageable(); RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() + .keyword(null) .latitude(37.6115) .longitude(127.034) .radius(5.0) @@ -368,6 +370,50 @@ void findAllNearByLocation_noResult() { } +// @DisplayName("위치 기반으로 반경 내에 모집글을 키워드로 검색하여 반환한다") +// @Test +// void findAllNearByLocationWithKeyword() { +// // given +// Pageable pageable = getPageable(); +// +// RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() +// .keyword("도서관") +// .latitude(37.5935) +// .longitude(126.9780) +// .radius(5.0) +// .pageable(pageable) +// .build(); +// +// // when +// Page result = recruitBoardRepository.findAllNearby(condition); +// +// // then +// assertThat(result).isNotNull(); +// assertThat(result.getTotalElements()).isEqualTo(2); +// } + +// @DisplayName("키워드 없이 검색시 위치 기반으로 반경 내에 모집글을 반환한다") +// @Test +// void findAllNearByLocationWithNull() { +// // given +// Pageable pageable = getPageable(); +// +// RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() +// .keyword("") +// .latitude(37.5935) +// .longitude(126.9780) +// .radius(5.0) +// .pageable(pageable) +// .build(); +// +// // when +// Page result = recruitBoardRepository.findAllNearby(condition); +// +// // then +// assertThat(result).isNotNull(); +// assertThat(result.getTotalElements()).isEqualTo(28); +// } + @DisplayName("기관 아이디로 모집글 리스트를 조회할 수 있다.") @Test void findAllByCenterId() { @@ -435,6 +481,7 @@ void saveDocuments() { //given Pageable pageable = getPageable(); RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() + .keyword("저장") .pageable(pageable) .build(); @@ -451,7 +498,7 @@ void saveDocuments() { recruitBoardRepository.saveDocuments(recruitBoards); //then - Page findBoard = recruitBoardRepository.findByRecruitBoardsContaining("저장", condition); + Page findBoard = recruitBoardRepository.findByRecruitBoardsContaining(condition); assertThat(findBoard).isNotNull(); assertThat(findBoard.getTotalElements()).isEqualTo(2); diff --git a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java index 2112381b5..141e972f0 100644 --- a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java +++ b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java @@ -6,7 +6,9 @@ import com.somemore.location.domain.Location; import com.somemore.location.repository.LocationRepository; import com.somemore.recruitboard.domain.RecruitBoard; +import com.somemore.recruitboard.dto.condition.RecruitBoardNearByCondition; import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; +import com.somemore.recruitboard.dto.response.RecruitBoardDetailResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; import com.somemore.recruitboard.repository.RecruitBoardRepository; import org.junit.jupiter.api.BeforeEach; @@ -33,6 +35,9 @@ public class RecruitBoardDocumentServiceTest extends IntegrationTestSupport { @Autowired private RecruitBoardDocumentService recruitBoardDocumentService; + @Autowired + private RecruitBoardQueryService recruitBoardQueryService; + @Autowired private RecruitBoardRepository recruitBoardRepository; @@ -66,11 +71,12 @@ void getRecruitBoardBySearch() { //given Pageable pageable = getPageable(); RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() + .keyword("노인") .pageable(pageable) .build(); //when - Page dtos = recruitBoardDocumentService.getRecruitBoardBySearch("노인", condition); + Page dtos = recruitBoardDocumentService.getRecruitBoardBySearch(condition); //then assertThat(dtos).isNotNull(); @@ -80,6 +86,50 @@ void getRecruitBoardBySearch() { assertThat(dtos.getTotalPages()).isEqualTo(1); } +// @DisplayName("위치 기반으로 주변 모집글을 페이징하여 조회할 수 있다") +// @Test +// void getRecruitBoardsNearBy() { +// // given +// Pageable pageable = getPageable(); +// RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() +// .keyword(null) +// .latitude(37.5935) +// .longitude(126.9780) +// .radius(5.0) +// .pageable(pageable) +// .build(); +// +// // when +// Page result = recruitBoardQueryService.getRecruitBoardsNearby( +// condition); +// +// // then +// assertThat(result).isNotNull(); +// assertThat(result.getTotalElements()).isEqualTo(23); +// assertThat(result.getContent()).isNotEmpty(); +// } + +// @DisplayName("키워드 없이 검색시 전체 모집글을 조회한다. (service)") +// @Test +// void getRecruitBoardBySearchWithNull() { +// //given +// Pageable pageable = getPageable(); +// RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() +// .keyword("") +// .pageable(pageable) +// .build(); +// +// //when +// Page dtos = recruitBoardDocumentService.getRecruitBoardBySearch(condition); +// +// //then +// assertThat(dtos).isNotNull(); +// assertThat(dtos.getContent()).isNotNull(); +// assertThat(dtos.getTotalElements()).isEqualTo(23); +// assertThat(dtos.getSize()).isEqualTo(5); +// assertThat(dtos.getTotalPages()).isEqualTo(5); +// } + private Pageable getPageable() { Sort sort = Sort.by(Sort.Order.desc("created_at")); return PageRequest.of(0, 5, sort); diff --git a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardQueryServiceTest.java b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardQueryServiceTest.java index 533ef93e3..625af1a36 100644 --- a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardQueryServiceTest.java +++ b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardQueryServiceTest.java @@ -151,36 +151,6 @@ void getAllWithCenter() { assertThat(dtos.getContent().getFirst().center().name()).isEqualTo(name); } - @DisplayName("위치 기반으로 주변 모집글을 페이징하여 조회할 수 있다") - @Test - void getRecruitBoardsNearBy() { - // given - Center center = createCenter(); - centerRepository.save(center); - Location location = createLocation(); - locationRepository.save(location); - - RecruitBoard board = createRecruitBoard(center.getId(), location.getId()); - recruitBoardRepository.save(board); - - Pageable pageable = getPageable(); - RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() - .latitude(location.getLatitude().doubleValue()) - .longitude(location.getLongitude().doubleValue()) - .radius(3.0) - .pageable(pageable) - .build(); - - // when - Page result = recruitBoardQueryService.getRecruitBoardsNearby( - condition); - - // then - assertThat(result).isNotEmpty(); - assertThat(result.getTotalElements()).isEqualTo(1); - assertThat(result.getContent().getFirst().id()).isEqualTo(board.getId()); - } - @DisplayName("기관 아이디로 모집글을 페이징하여 조회할 수 있다") @Test void getRecruitBoardsByCenterId() { @@ -294,6 +264,7 @@ void saveRecruitBoardDocuments() { Pageable pageable = getPageable(); RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() + .keyword("저장") .pageable(pageable) .build(); @@ -310,7 +281,7 @@ void saveRecruitBoardDocuments() { recruitBoardDocumentService.saveRecruitBoardDocuments(recruitBoards); //then - Page findBoard = recruitBoardDocumentService.getRecruitBoardBySearch("저장", condition); + Page findBoard = recruitBoardDocumentService.getRecruitBoardBySearch(condition); assertThat(findBoard).isNotNull(); assertThat(findBoard.getTotalElements()).isEqualTo(2); From 0cd0c2be46d105ac2a8b6961fbdea647ff167c83 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 10:38:19 +0900 Subject: [PATCH 18/23] =?UTF-8?q?chore(search):=20=EA=B0=9C=ED=96=89=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/somemore/recruitboard/domain/RecruitBoardDocument.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/somemore/recruitboard/domain/RecruitBoardDocument.java b/src/main/java/com/somemore/recruitboard/domain/RecruitBoardDocument.java index e95aa422f..0af2d3bb4 100644 --- a/src/main/java/com/somemore/recruitboard/domain/RecruitBoardDocument.java +++ b/src/main/java/com/somemore/recruitboard/domain/RecruitBoardDocument.java @@ -27,4 +27,4 @@ public RecruitBoardDocument(Long id, String title, String content) { this.title = title; this.content = content; } -} \ No newline at end of file +} From 9abb6ab258a56f8b0c051a8d30f4408912d7009c Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 10:40:15 +0900 Subject: [PATCH 19/23] =?UTF-8?q?refactor(search):=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?recruitBoard=20=EA=B2=80=EC=83=89=20/=20elasicsearch=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecruitBoardQueryApiController.java | 4 +- .../RecruitBoardSearchApiController.java | 85 +++++++++++++++++++ .../repository/RecruitBoardRepository.java | 3 + .../RecruitBoardRepositoryImpl.java | 34 ++++++++ .../query/RecruitBoardDocumentService.java | 11 +++ .../query/RecruitBoardDocumentUseCase.java | 4 + 6 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/somemore/recruitboard/controller/RecruitBoardSearchApiController.java diff --git a/src/main/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiController.java b/src/main/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiController.java index b0e56a87a..5465f066b 100644 --- a/src/main/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiController.java +++ b/src/main/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiController.java @@ -11,7 +11,6 @@ import com.somemore.recruitboard.dto.response.RecruitBoardResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithLocationResponseDto; -import com.somemore.recruitboard.usecase.query.RecruitBoardDocumentUseCase; import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -33,7 +32,6 @@ public class RecruitBoardQueryApiController { private final RecruitBoardQueryUseCase recruitBoardQueryUseCase; - private final RecruitBoardDocumentUseCase recruitBoardDocumentUseCase; @GetMapping("/recruit-board/{id}") @Operation(summary = "봉사 모집글 상세 조회", description = "특정 모집글의 상세 정보를 조회합니다.") @@ -85,7 +83,7 @@ public ApiResponse> getAllBySearch( return ApiResponse.ok( 200, - recruitBoardDocumentUseCase.getRecruitBoardBySearch(condition), + recruitBoardQueryUseCase.getAllWithCenter(condition), "봉사 활동 모집글 검색 조회 성공" ); } diff --git a/src/main/java/com/somemore/recruitboard/controller/RecruitBoardSearchApiController.java b/src/main/java/com/somemore/recruitboard/controller/RecruitBoardSearchApiController.java new file mode 100644 index 000000000..69902dfa6 --- /dev/null +++ b/src/main/java/com/somemore/recruitboard/controller/RecruitBoardSearchApiController.java @@ -0,0 +1,85 @@ +package com.somemore.recruitboard.controller; + +import com.somemore.global.common.response.ApiResponse; +import com.somemore.recruitboard.domain.RecruitStatus; +import com.somemore.recruitboard.domain.VolunteerCategory; +import com.somemore.recruitboard.dto.condition.RecruitBoardNearByCondition; +import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; +import com.somemore.recruitboard.dto.response.RecruitBoardDetailResponseDto; +import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; +import com.somemore.recruitboard.usecase.query.RecruitBoardDocumentUseCase; +import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import static org.springframework.data.domain.Sort.Direction.DESC; + +@Tag(name = "Recruit Board Search API", description = "봉사 활동 모집 검색 관련 API") +@RequiredArgsConstructor +@RequestMapping("/api_v1") +@RestController +public class RecruitBoardSearchApiController { + + private final RecruitBoardQueryUseCase recruitBoardQueryUseCase; + private final RecruitBoardDocumentUseCase recruitBoardDocumentUseCase; + + @GetMapping("/recruit-boards/search") + @Operation(summary = "모집글 검색 조회", description = "검색 조건을 기반으로 모집글을 조회합니다.") + public ApiResponse> getAllBySearch( + @PageableDefault(sort = "created_at", direction = DESC) Pageable pageable, + @RequestParam(required = false) String keyword, + @RequestParam(required = false) VolunteerCategory category, + @RequestParam(required = false) String region, + @RequestParam(required = false) Boolean admitted, + @RequestParam(required = false) RecruitStatus status + ) { + RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() + .keyword(keyword) + .category(category) + .region(region) + .admitted(admitted) + .status(status) + .pageable(pageable) + .build(); + + return ApiResponse.ok( + 200, + recruitBoardDocumentUseCase.getRecruitBoardBySearch(condition), + "봉사 활동 모집글 검색 조회 성공" + ); + } + + @GetMapping("/recruit-boards/nearby") + @Operation(summary = "근처 모집글 조회", description = "주변 반경 내의 봉사 모집글을 조회합니다.") + public ApiResponse> getNearby( + @RequestParam double latitude, + @RequestParam double longitude, + @RequestParam(required = false, defaultValue = "5") double radius, + @RequestParam(required = false) String keyword, + @RequestParam(required = false, defaultValue = "RECRUITING") RecruitStatus status, + @PageableDefault(sort = "created_at", direction = DESC) Pageable pageable + ) { + RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() + .latitude(latitude) + .longitude(longitude) + .radius(radius) + .keyword(keyword) + .status(status) + .pageable(pageable) + .build(); + + return ApiResponse.ok( + 200, + recruitBoardDocumentUseCase.getRecruitBoardsNearbyWithKeyword(condition), + "근처 봉사 활동 모집글 조회 성공" + ); + } +} diff --git a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepository.java b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepository.java index f5c45582a..282d926a5 100644 --- a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepository.java +++ b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepository.java @@ -25,6 +25,9 @@ public interface RecruitBoardRepository { Page findAllNearby(RecruitBoardNearByCondition condition); + Page findAllNearbyWithKeyword(RecruitBoardNearByCondition condition); + + Page findAllByCenterId(UUID centerId, RecruitBoardSearchCondition condition); List findNotCompletedIdsByCenterId(UUID centerId); diff --git a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImpl.java b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImpl.java index 0dc01c902..14609a3e4 100644 --- a/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImpl.java +++ b/src/main/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImpl.java @@ -138,6 +138,40 @@ public Page findAllNearby(RecruitBoardNearByCondition condit QLocation location = QLocation.location; QCenter center = QCenter.center; + Pageable pageable = condition.pageable(); + + BooleanExpression predicate = locationBetween(condition) + .and(keywordEq(condition.keyword())) + .and(statusEq(condition.status())) + .and(isNotDeleted()); + + List content = queryFactory + .select(getRecruitBoardDetailConstructorExpression(recruitBoard, location, center)) + .from(recruitBoard) + .join(location).on(recruitBoard.locationId.eq(location.id)) + .join(center).on(recruitBoard.centerId.eq(center.id)) + .where(predicate) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(toOrderSpecifiers(pageable.getSort())) + .fetch(); + + JPAQuery countQuery = queryFactory + .select(recruitBoard.count()) + .from(recruitBoard) + .join(location).on(recruitBoard.locationId.eq(location.id)) + .join(center).on(recruitBoard.centerId.eq(center.id)) + .where(predicate); + + return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchOne); + } + + @Override + public Page findAllNearbyWithKeyword(RecruitBoardNearByCondition condition) { + QRecruitBoard recruitBoard = QRecruitBoard.recruitBoard; + QLocation location = QLocation.location; + QCenter center = QCenter.center; + List boardDocuments = getBoardDocuments(condition.keyword()); List boardIds = boardDocuments.stream() diff --git a/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentService.java b/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentService.java index 65b4da2df..275320129 100644 --- a/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentService.java +++ b/src/main/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentService.java @@ -1,9 +1,12 @@ package com.somemore.recruitboard.service.query; import com.somemore.recruitboard.domain.RecruitBoard; +import com.somemore.recruitboard.dto.condition.RecruitBoardNearByCondition; import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; +import com.somemore.recruitboard.dto.response.RecruitBoardDetailResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; import com.somemore.recruitboard.repository.RecruitBoardRepository; +import com.somemore.recruitboard.repository.mapper.RecruitBoardDetail; import com.somemore.recruitboard.repository.mapper.RecruitBoardWithCenter; import com.somemore.recruitboard.usecase.query.RecruitBoardDocumentUseCase; import lombok.RequiredArgsConstructor; @@ -26,6 +29,14 @@ public Page getRecruitBoardBySearch(RecruitBo return boards.map(RecruitBoardWithCenterResponseDto::from); } + @Transactional(readOnly = true) + @Override + public Page getRecruitBoardsNearbyWithKeyword( + RecruitBoardNearByCondition condition) { + Page boards = recruitBoardRepository.findAllNearbyWithKeyword(condition); + return boards.map(RecruitBoardDetailResponseDto::from); + } + @Transactional @Override public void saveRecruitBoardDocuments(List recruitBoards) { diff --git a/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardDocumentUseCase.java b/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardDocumentUseCase.java index 17346186f..477a6da80 100644 --- a/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardDocumentUseCase.java +++ b/src/main/java/com/somemore/recruitboard/usecase/query/RecruitBoardDocumentUseCase.java @@ -1,7 +1,9 @@ package com.somemore.recruitboard.usecase.query; import com.somemore.recruitboard.domain.RecruitBoard; +import com.somemore.recruitboard.dto.condition.RecruitBoardNearByCondition; import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; +import com.somemore.recruitboard.dto.response.RecruitBoardDetailResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; import org.springframework.data.domain.Page; @@ -9,5 +11,7 @@ public interface RecruitBoardDocumentUseCase { Page getRecruitBoardBySearch(RecruitBoardSearchCondition condition); + Page getRecruitBoardsNearbyWithKeyword( + RecruitBoardNearByCondition condition); void saveRecruitBoardDocuments(List recruitBoards); } From fc492f469a5173ed91ad0299c961981669b2245f Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 10:40:33 +0900 Subject: [PATCH 20/23] =?UTF-8?q?test(search):=20=EA=B8=B0=EC=A1=B4=20recr?= =?UTF-8?q?uitBoard=20=EA=B2=80=EC=83=89=20/=20elasicsearch=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EB=B6=84=EB=A6=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RecruitBoardQueryApiControllerTest.java | 91 +++++++++---------- .../RecruitBoardSearchApiControllerTest.java | 88 ++++++++++++++++++ .../RecruitBoardDocumentRepositoryTest.java | 25 +++++ .../RecruitBoardRepositoryImplTest.java | 88 +++++------------- .../RecruitBoardDocumentServiceTest.java | 57 ++++++++---- .../query/RecruitBoardQueryServiceTest.java | 30 ++++++ 6 files changed, 247 insertions(+), 132 deletions(-) create mode 100644 src/test/java/com/somemore/recruitboard/controller/RecruitBoardSearchApiControllerTest.java diff --git a/src/test/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiControllerTest.java b/src/test/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiControllerTest.java index 3efcff89f..a637acf7e 100644 --- a/src/test/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiControllerTest.java +++ b/src/test/java/com/somemore/recruitboard/controller/RecruitBoardQueryApiControllerTest.java @@ -17,7 +17,6 @@ import com.somemore.recruitboard.dto.response.RecruitBoardResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithLocationResponseDto; -import com.somemore.recruitboard.usecase.query.RecruitBoardDocumentUseCase; import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; import java.util.Collections; import java.util.UUID; @@ -38,9 +37,6 @@ class RecruitBoardQueryApiControllerTest extends ControllerTestSupport { @MockBean private RecruitBoardQueryUseCase recruitBoardQueryUseCase; - @MockBean - private RecruitBoardDocumentUseCase documentUseCase; - @Test @DisplayName("모집글 ID로 상세 조회할 수 있다.") void getById() throws Exception { @@ -52,11 +48,11 @@ void getById() throws Exception { // when // then mockMvc.perform(get("/api/recruit-board/{id}", recruitBoardId) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.code").value(200)) - .andExpect(jsonPath("$.data").exists()) - .andExpect(jsonPath("$.message").value("봉사 활동 모집 상세 조회 성공")); + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(200)) + .andExpect(jsonPath("$.data").exists()) + .andExpect(jsonPath("$.message").value("봉사 활동 모집 상세 조회 성공")); verify(recruitBoardQueryUseCase, times(1)).getWithLocationById(recruitBoardId); } @@ -68,19 +64,19 @@ void getAll() throws Exception { Page page = new PageImpl<>(Collections.emptyList()); given(recruitBoardQueryUseCase.getAllWithCenter(any(RecruitBoardSearchCondition.class))) - .willReturn(page); + .willReturn(page); // when // then mockMvc.perform(get("/api/recruit-boards") - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.code").value(200)) - .andExpect(jsonPath("$.data").exists()) - .andExpect(jsonPath("$.message").value("봉사 활동 모집글 리스트 조회 성공")); + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(200)) + .andExpect(jsonPath("$.data").exists()) + .andExpect(jsonPath("$.message").value("봉사 활동 모집글 리스트 조회 성공")); verify(recruitBoardQueryUseCase, times(1)).getAllWithCenter( - any(RecruitBoardSearchCondition.class)); + any(RecruitBoardSearchCondition.class)); } @Test @@ -89,21 +85,22 @@ void getAllBySearch() throws Exception { // given Page page = new PageImpl<>(Collections.emptyList()); - given(documentUseCase.getRecruitBoardBySearch(any(RecruitBoardSearchCondition.class))) - .willReturn(page); + given(recruitBoardQueryUseCase.getAllWithCenter(any(RecruitBoardSearchCondition.class))) + .willReturn(page); // when // then mockMvc.perform(get("/api/recruit-boards/search") - .param("keyword", "volunteer") - .param("category", ADMINISTRATIVE_SUPPORT.name()) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.code").value(200)) - .andExpect(jsonPath("$.data").exists()) - .andExpect(jsonPath("$.message").value("봉사 활동 모집글 검색 조회 성공")); - - verify(documentUseCase, times(1)).getRecruitBoardBySearch(any(RecruitBoardSearchCondition.class)); + .param("keyword", "volunteer") + .param("category", ADMINISTRATIVE_SUPPORT.name()) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(200)) + .andExpect(jsonPath("$.data").exists()) + .andExpect(jsonPath("$.message").value("봉사 활동 모집글 검색 조회 성공")); + + verify(recruitBoardQueryUseCase, times(1)).getAllWithCenter( + any(RecruitBoardSearchCondition.class)); } @Test @@ -112,23 +109,23 @@ void getNearby() throws Exception { // given Page page = new PageImpl<>(Collections.emptyList()); given(recruitBoardQueryUseCase.getRecruitBoardsNearby( - any(RecruitBoardNearByCondition.class) + any(RecruitBoardNearByCondition.class) )).willReturn(page); // when // then mockMvc.perform(get("/api/recruit-boards/nearby") - .param("latitude", "37.5665") - .param("longitude", "126.9780") - .param("radius", "10") - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.code").value(200)) - .andExpect(jsonPath("$.data").exists()) - .andExpect(jsonPath("$.message").value("근처 봉사 활동 모집글 조회 성공")); + .param("latitude", "37.5665") + .param("longitude", "126.9780") + .param("radius", "10") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(200)) + .andExpect(jsonPath("$.data").exists()) + .andExpect(jsonPath("$.message").value("근처 봉사 활동 모집글 조회 성공")); verify(recruitBoardQueryUseCase, times(1)).getRecruitBoardsNearby( - any(RecruitBoardNearByCondition.class)); + any(RecruitBoardNearByCondition.class)); } @Test @@ -139,20 +136,20 @@ void getRecruitBoardsByCenterId() throws Exception { Page page = new PageImpl<>(Collections.emptyList()); given(recruitBoardQueryUseCase.getRecruitBoardsByCenterId(eq(centerId), - any(RecruitBoardSearchCondition.class))) - .willReturn(page); + any(RecruitBoardSearchCondition.class))) + .willReturn(page); // when // then mockMvc.perform(get("/api/recruit-boards/center/{centerId}", centerId) - .param("keyword", "volunteer") - .param("category", ADMINISTRATIVE_SUPPORT.name()) - .accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.data").exists()) - .andExpect(jsonPath("$.message").value("기관 봉사 활동 모집글 조회 성공")); + .param("keyword", "volunteer") + .param("category", ADMINISTRATIVE_SUPPORT.name()) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.data").exists()) + .andExpect(jsonPath("$.message").value("기관 봉사 활동 모집글 조회 성공")); verify(recruitBoardQueryUseCase, times(1)).getRecruitBoardsByCenterId(eq(centerId), - any(RecruitBoardSearchCondition.class)); + any(RecruitBoardSearchCondition.class)); } -} +} \ No newline at end of file diff --git a/src/test/java/com/somemore/recruitboard/controller/RecruitBoardSearchApiControllerTest.java b/src/test/java/com/somemore/recruitboard/controller/RecruitBoardSearchApiControllerTest.java new file mode 100644 index 000000000..e1b903097 --- /dev/null +++ b/src/test/java/com/somemore/recruitboard/controller/RecruitBoardSearchApiControllerTest.java @@ -0,0 +1,88 @@ +package com.somemore.recruitboard.controller; + +import com.somemore.ControllerTestSupport; +import com.somemore.recruitboard.dto.condition.RecruitBoardNearByCondition; +import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; +import com.somemore.recruitboard.dto.response.RecruitBoardDetailResponseDto; +import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; +import com.somemore.recruitboard.usecase.query.RecruitBoardDocumentUseCase; +import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import java.util.Collections; + +import static com.somemore.recruitboard.domain.VolunteerCategory.ADMINISTRATIVE_SUPPORT; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class RecruitBoardSearchApiControllerTest extends ControllerTestSupport { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private RecruitBoardQueryUseCase recruitBoardQueryUseCase; + + @MockBean + private RecruitBoardDocumentUseCase documentUseCase; + + @Test + @DisplayName("모집글을 검색 조건으로 페이징 조회할 수 있다.") + void getAllBySearch() throws Exception { + // given + Page page = new PageImpl<>(Collections.emptyList()); + + given(documentUseCase.getRecruitBoardBySearch(any(RecruitBoardSearchCondition.class))) + .willReturn(page); + + // when + // then + mockMvc.perform(get("/api_v1/recruit-boards/search") + .param("keyword", "volunteer") + .param("category", ADMINISTRATIVE_SUPPORT.name()) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(200)) + .andExpect(jsonPath("$.data").exists()) + .andExpect(jsonPath("$.message").value("봉사 활동 모집글 검색 조회 성공")); + + verify(documentUseCase, times(1)).getRecruitBoardBySearch(any(RecruitBoardSearchCondition.class)); + } + + @Test + @DisplayName("위치 기반으로 근처 있는 모집글 페이징 조회할 수 있다.") + void getNearby() throws Exception { + // given + Page page = new PageImpl<>(Collections.emptyList()); + given(documentUseCase.getRecruitBoardsNearbyWithKeyword( + any(RecruitBoardNearByCondition.class) + )).willReturn(page); + + // when + // then + mockMvc.perform(get("/api_v1/recruit-boards/nearby") + .param("latitude", "37.5665") + .param("longitude", "126.9780") + .param("radius", "10") + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(200)) + .andExpect(jsonPath("$.data").exists()) + .andExpect(jsonPath("$.message").value("근처 봉사 활동 모집글 조회 성공")); + + verify(documentUseCase, times(1)).getRecruitBoardsNearbyWithKeyword( + any(RecruitBoardNearByCondition.class)); + } +} diff --git a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java index 9976ab006..4e46b94c5 100644 --- a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java +++ b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java @@ -6,7 +6,9 @@ import com.somemore.location.domain.Location; import com.somemore.location.repository.LocationRepository; import com.somemore.recruitboard.domain.RecruitBoard; +import com.somemore.recruitboard.dto.condition.RecruitBoardNearByCondition; import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; +import com.somemore.recruitboard.repository.mapper.RecruitBoardDetail; import com.somemore.recruitboard.repository.mapper.RecruitBoardWithCenter; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -94,6 +96,29 @@ void findByRecruitBoardsContaining() { // assertThat(findBoards.getTotalElements()).isEqualTo(23); // assertThat(findBoards.getSize()).isEqualTo(5); // assertThat(findBoards.getTotalPages()).isEqualTo(5); +// } + +// @DisplayName("위치 기반으로 반경 내에 모집글을 반환한다") +// @Test +// void findAllNearByLocationWithKeyword() { +// // given +// Pageable pageable = getPageable(); +// +// RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() +// .keyword(null) +// .latitude(37.5935) +// .longitude(126.9780) +// .radius(5.0) +// .pageable(pageable) +// .build(); +// +// // when +// Page result = recruitBoardRepository.findAllNearbyWithKeyword(condition); +// +// // then +// assertThat(result).isNotNull(); +// assertThat(result.getTotalElements()).isEqualTo(23); +// assertThat(result.getContent()).isNotEmpty(); // } private Pageable getPageable() { diff --git a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImplTest.java b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImplTest.java index 60329a848..986e91e83 100644 --- a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImplTest.java +++ b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardRepositoryImplTest.java @@ -323,28 +323,27 @@ void findAllWithCenterByStatus() { status); } -// @DisplayName("위치 기반으로 반경 내에 모집글을 반환한다") -// @Test -// void findAllNearByLocation() { -// // given -// Pageable pageable = getPageable(); -// -// RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() -// .keyword(null) -// .latitude(37.5935) -// .longitude(126.9780) -// .radius(5.0) -// .pageable(pageable) -// .build(); -// -// // when -// Page result = recruitBoardRepository.findAllNearby(condition); -// -// // then -// assertThat(result).isNotNull(); -// assertThat(result.getTotalElements()).isEqualTo(28); -// assertThat(result.getContent()).isNotEmpty(); -// } + @DisplayName("위치 기반으로 반경 내에 모집글을 반환한다") + @Test + void findAllNearByLocation() { + // given + Pageable pageable = getPageable(); + + RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() + .latitude(37.5935) + .longitude(126.9780) + .radius(5.0) + .pageable(pageable) + .build(); + + // when + Page result = recruitBoardRepository.findAllNearby(condition); + + // then + assertThat(result).isNotNull(); + assertThat(result.getTotalElements()).isEqualTo(boards.size()); + assertThat(result.getContent()).isNotEmpty(); + } @DisplayName("위치 기반으로 반경 내에 모집글이 없으면 빈 페이지를 반환한다") @Test @@ -353,7 +352,6 @@ void findAllNearByLocation_noResult() { Pageable pageable = getPageable(); RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() - .keyword(null) .latitude(37.6115) .longitude(127.034) .radius(5.0) @@ -370,50 +368,6 @@ void findAllNearByLocation_noResult() { } -// @DisplayName("위치 기반으로 반경 내에 모집글을 키워드로 검색하여 반환한다") -// @Test -// void findAllNearByLocationWithKeyword() { -// // given -// Pageable pageable = getPageable(); -// -// RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() -// .keyword("도서관") -// .latitude(37.5935) -// .longitude(126.9780) -// .radius(5.0) -// .pageable(pageable) -// .build(); -// -// // when -// Page result = recruitBoardRepository.findAllNearby(condition); -// -// // then -// assertThat(result).isNotNull(); -// assertThat(result.getTotalElements()).isEqualTo(2); -// } - -// @DisplayName("키워드 없이 검색시 위치 기반으로 반경 내에 모집글을 반환한다") -// @Test -// void findAllNearByLocationWithNull() { -// // given -// Pageable pageable = getPageable(); -// -// RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() -// .keyword("") -// .latitude(37.5935) -// .longitude(126.9780) -// .radius(5.0) -// .pageable(pageable) -// .build(); -// -// // when -// Page result = recruitBoardRepository.findAllNearby(condition); -// -// // then -// assertThat(result).isNotNull(); -// assertThat(result.getTotalElements()).isEqualTo(28); -// } - @DisplayName("기관 아이디로 모집글 리스트를 조회할 수 있다.") @Test void findAllByCenterId() { diff --git a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java index 141e972f0..db524f661 100644 --- a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java +++ b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java @@ -11,6 +11,7 @@ import com.somemore.recruitboard.dto.response.RecruitBoardDetailResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; import com.somemore.recruitboard.repository.RecruitBoardRepository; +import com.somemore.recruitboard.repository.mapper.RecruitBoardDetail; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -35,9 +36,6 @@ public class RecruitBoardDocumentServiceTest extends IntegrationTestSupport { @Autowired private RecruitBoardDocumentService recruitBoardDocumentService; - @Autowired - private RecruitBoardQueryService recruitBoardQueryService; - @Autowired private RecruitBoardRepository recruitBoardRepository; @@ -86,7 +84,28 @@ void getRecruitBoardBySearch() { assertThat(dtos.getTotalPages()).isEqualTo(1); } -// @DisplayName("위치 기반으로 주변 모집글을 페이징하여 조회할 수 있다") +// @DisplayName("키워드 없이 검색시 전체 모집글을 조회한다. (service)") +// @Test +// void getRecruitBoardBySearchWithNull() { +// //given +// Pageable pageable = getPageable(); +// RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() +// .keyword("") +// .pageable(pageable) +// .build(); +// +// //when +// Page dtos = recruitBoardDocumentService.getRecruitBoardBySearch(condition); +// +// //then +// assertThat(dtos).isNotNull(); +// assertThat(dtos.getContent()).isNotNull(); +// assertThat(dtos.getTotalElements()).isEqualTo(23); +// assertThat(dtos.getSize()).isEqualTo(5); +// assertThat(dtos.getTotalPages()).isEqualTo(5); +// } + +// @DisplayName("위치 기반으로 주변 모집글을 페이징하여 조회할 수 있다. (service)") // @Test // void getRecruitBoardsNearBy() { // // given @@ -100,7 +119,7 @@ void getRecruitBoardBySearch() { // .build(); // // // when -// Page result = recruitBoardQueryService.getRecruitBoardsNearby( +// Page result = recruitBoardDocumentService.getRecruitBoardsNearbyWithKeyword( // condition); // // // then @@ -109,25 +128,27 @@ void getRecruitBoardBySearch() { // assertThat(result.getContent()).isNotEmpty(); // } -// @DisplayName("키워드 없이 검색시 전체 모집글을 조회한다. (service)") +// @DisplayName("위치 기반으로 반경 내에 모집글을 키워드로 검색하여 반환한다. (service)") // @Test -// void getRecruitBoardBySearchWithNull() { -// //given +// void findAllNearByLocationWithKeyword() { +// // given // Pageable pageable = getPageable(); -// RecruitBoardSearchCondition condition = RecruitBoardSearchCondition.builder() -// .keyword("") +// +// RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() +// .keyword("도서관") +// .latitude(37.5935) +// .longitude(126.9780) +// .radius(5.0) // .pageable(pageable) // .build(); // -// //when -// Page dtos = recruitBoardDocumentService.getRecruitBoardBySearch(condition); +// // when +// Page result = recruitBoardDocumentService.getRecruitBoardsNearbyWithKeyword( +// condition); // -// //then -// assertThat(dtos).isNotNull(); -// assertThat(dtos.getContent()).isNotNull(); -// assertThat(dtos.getTotalElements()).isEqualTo(23); -// assertThat(dtos.getSize()).isEqualTo(5); -// assertThat(dtos.getTotalPages()).isEqualTo(5); +// // then +// assertThat(result).isNotNull(); +// assertThat(result.getTotalElements()).isEqualTo(1); // } private Pageable getPageable() { diff --git a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardQueryServiceTest.java b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardQueryServiceTest.java index 625af1a36..2abc28610 100644 --- a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardQueryServiceTest.java +++ b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardQueryServiceTest.java @@ -151,6 +151,36 @@ void getAllWithCenter() { assertThat(dtos.getContent().getFirst().center().name()).isEqualTo(name); } + @DisplayName("위치 기반으로 주변 모집글을 페이징하여 조회할 수 있다") + @Test + void getRecruitBoardsNearBy() { + // given + Center center = createCenter(); + centerRepository.save(center); + Location location = createLocation(); + locationRepository.save(location); + + RecruitBoard board = createRecruitBoard(center.getId(), location.getId()); + recruitBoardRepository.save(board); + + Pageable pageable = getPageable(); + RecruitBoardNearByCondition condition = RecruitBoardNearByCondition.builder() + .latitude(location.getLatitude().doubleValue()) + .longitude(location.getLongitude().doubleValue()) + .radius(3.0) + .pageable(pageable) + .build(); + + // when + Page result = recruitBoardQueryService.getRecruitBoardsNearby( + condition); + + // then + assertThat(result).isNotEmpty(); + assertThat(result.getTotalElements()).isEqualTo(1); + assertThat(result.getContent().getFirst().id()).isEqualTo(board.getId()); + } + @DisplayName("기관 아이디로 모집글을 페이징하여 조회할 수 있다") @Test void getRecruitBoardsByCenterId() { From fd514393d586c6bf7b2da357938366ee965b9adf Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 10:42:19 +0900 Subject: [PATCH 21/23] =?UTF-8?q?test(search):=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20import=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/RecruitBoardSearchApiControllerTest.java | 4 ---- .../repository/RecruitBoardDocumentRepositoryTest.java | 2 -- .../service/query/RecruitBoardDocumentServiceTest.java | 3 --- 3 files changed, 9 deletions(-) diff --git a/src/test/java/com/somemore/recruitboard/controller/RecruitBoardSearchApiControllerTest.java b/src/test/java/com/somemore/recruitboard/controller/RecruitBoardSearchApiControllerTest.java index e1b903097..9f670c1e9 100644 --- a/src/test/java/com/somemore/recruitboard/controller/RecruitBoardSearchApiControllerTest.java +++ b/src/test/java/com/somemore/recruitboard/controller/RecruitBoardSearchApiControllerTest.java @@ -6,7 +6,6 @@ import com.somemore.recruitboard.dto.response.RecruitBoardDetailResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; import com.somemore.recruitboard.usecase.query.RecruitBoardDocumentUseCase; -import com.somemore.recruitboard.usecase.query.RecruitBoardQueryUseCase; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -32,9 +31,6 @@ public class RecruitBoardSearchApiControllerTest extends ControllerTestSupport { @Autowired private MockMvc mockMvc; - @MockBean - private RecruitBoardQueryUseCase recruitBoardQueryUseCase; - @MockBean private RecruitBoardDocumentUseCase documentUseCase; diff --git a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java index 4e46b94c5..dec972e8c 100644 --- a/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java +++ b/src/test/java/com/somemore/recruitboard/repository/RecruitBoardDocumentRepositoryTest.java @@ -6,9 +6,7 @@ import com.somemore.location.domain.Location; import com.somemore.location.repository.LocationRepository; import com.somemore.recruitboard.domain.RecruitBoard; -import com.somemore.recruitboard.dto.condition.RecruitBoardNearByCondition; import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; -import com.somemore.recruitboard.repository.mapper.RecruitBoardDetail; import com.somemore.recruitboard.repository.mapper.RecruitBoardWithCenter; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; diff --git a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java index db524f661..910ff880f 100644 --- a/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java +++ b/src/test/java/com/somemore/recruitboard/service/query/RecruitBoardDocumentServiceTest.java @@ -6,12 +6,9 @@ import com.somemore.location.domain.Location; import com.somemore.location.repository.LocationRepository; import com.somemore.recruitboard.domain.RecruitBoard; -import com.somemore.recruitboard.dto.condition.RecruitBoardNearByCondition; import com.somemore.recruitboard.dto.condition.RecruitBoardSearchCondition; -import com.somemore.recruitboard.dto.response.RecruitBoardDetailResponseDto; import com.somemore.recruitboard.dto.response.RecruitBoardWithCenterResponseDto; import com.somemore.recruitboard.repository.RecruitBoardRepository; -import com.somemore.recruitboard.repository.mapper.RecruitBoardDetail; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; From 6856bedb54b41e13044b46fa95ae009b28cab578 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 12:25:11 +0900 Subject: [PATCH 22/23] =?UTF-8?q?test(search):=20elastic=20search=20uri=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/application-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml index 0128fe6c3..9e79bdba9 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application-test.yml @@ -70,9 +70,9 @@ default: elastic: search: - uri: localhost:9200 + uri: ec2-43-201-249-131.ap-northeast-2.compute.amazonaws.com:9200 username: elastic - password: somemore + password: changeme management: health: From 20ceb93d1b59c79d2e2c422f9c3c4d276e23ef76 Mon Sep 17 00:00:00 2001 From: ayoung-dev Date: Mon, 9 Dec 2024 12:40:04 +0900 Subject: [PATCH 23/23] =?UTF-8?q?test(search):=20test=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/CommunityBoardDocumentRepositoryTest.java | 2 +- .../service/board/CommunityBoardDocumentServiceTest.java | 2 +- .../community/service/board/CommunityBoardQueryServiceTest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/somemore/community/repository/CommunityBoardDocumentRepositoryTest.java b/src/test/java/com/somemore/community/repository/CommunityBoardDocumentRepositoryTest.java index d0f91356f..a18d78206 100644 --- a/src/test/java/com/somemore/community/repository/CommunityBoardDocumentRepositoryTest.java +++ b/src/test/java/com/somemore/community/repository/CommunityBoardDocumentRepositoryTest.java @@ -52,7 +52,7 @@ void findByCommunityBoardsContaining() { //then assertThat(findBoards).isNotNull(); - assertThat(findBoards.getTotalElements()).isEqualTo(9); + assertThat(findBoards.getTotalElements()).isEqualTo(10); assertThat(findBoards.getSize()).isEqualTo(10); assertThat(findBoards.getTotalPages()).isEqualTo(1); } diff --git a/src/test/java/com/somemore/community/service/board/CommunityBoardDocumentServiceTest.java b/src/test/java/com/somemore/community/service/board/CommunityBoardDocumentServiceTest.java index 8657f9088..14c348efd 100644 --- a/src/test/java/com/somemore/community/service/board/CommunityBoardDocumentServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/CommunityBoardDocumentServiceTest.java @@ -61,7 +61,7 @@ void getCommunityBoardBySearch() { //then assertThat(dtos).isNotNull(); assertThat(dtos.getContent()).isNotNull(); - assertThat(dtos.getTotalElements()).isEqualTo(9); + assertThat(dtos.getTotalElements()).isEqualTo(10); assertThat(dtos.getSize()).isEqualTo(10); assertThat(dtos.getTotalPages()).isEqualTo(1); } diff --git a/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java b/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java index d0caba76d..e695a91a1 100644 --- a/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java +++ b/src/test/java/com/somemore/community/service/board/CommunityBoardQueryServiceTest.java @@ -169,7 +169,7 @@ void saveCommunityBoardDocuments() { assertThat(dtos).isNotNull(); assertThat(dtos.getContent()).isNotNull(); - assertThat(dtos.getTotalElements()).isEqualTo(15); + assertThat(dtos.getTotalElements()).isEqualTo(16); assertThat(dtos.getSize()).isEqualTo(10); assertThat(dtos.getTotalPages()).isEqualTo(2);