From 97a39a58c3d5b66090fae531ed7c111e922e6a5a Mon Sep 17 00:00:00 2001 From: Jeonghoon Park <39729721+shb03323@users.noreply.github.com> Date: Mon, 14 Aug 2023 19:33:12 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=ED=95=9C=20?= =?UTF-8?q?=EC=84=9C=ED=8F=AC=ED=84=B0=EC=9D=98=20=EB=9F=AC=EB=84=88=20?= =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EC=A1=B0=ED=9A=8C=20API=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#342)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: RestAssured 및 Restdocs 테스트 컨벤션 적용 * feat: review status 상태 하나 추가 * feat: response dto 구현 * test: 인수 테스트 작성 * feat: 서포터와 리뷰 상태로 러너 게시글 최신순으로 조회하는 기능 구현 * feat: 서포터와 리뷰 상태로 러너 게시글 최신순으로 조회하는 서비스 구현 * feat: controller 작성 및 주석 처리 * refactor: 충돌 해결 * refactor: 페이지네이션 적용 * test: NOT_STARTED 인 테스트 진행 * test: restdocs 작성 * refactor: 서브 모듈 업데이트 * refactor: 개행 제거 * refactor: 코드 리뷰 반영 * refactor: 코드 리뷰 반영 * test: restdocs 테스트에 path parameter 추가 * test: 코드리뷰 반영 * test: 코드리뷰 반영 * refactor: 충돌 해결 --- .../controller/RunnerPostController.java | 24 +++ .../response/RunnerPostReadResponses.java | 7 + .../response/RunnerPostResponse.java | 24 ++- .../repository/RunnerPostRepository.java | 14 +- .../runnerpost/service/RunnerPostService.java | 3 + .../domain/runnerpost/vo/ReviewStatus.java | 4 + .../baton/assure/common/AssuredSupport.java | 33 +++-- .../SupporterFeedbackAssuredSupport.java | 1 + ...> SupporterFeedbackCreateAssuredTest.java} | 9 +- ...Support.java => MemberAssuredSupport.java} | 4 +- ...mberReadWithLoginedMemberAssuredTest.java} | 6 +- ...Support.java => RunnerAssuredSupport.java} | 31 ++-- .../runner/RunnerProfileAssuredReadTest.java | 56 ------- .../RunnerReadByRunnerIdAssuredTest.java | 42 ++++++ ...unnerReadWithLoginedRunnerAssuredTest.java | 30 ++++ ...Test.java => RunnerUpdateAssuredTest.java} | 16 +- .../runnerpost/RunnerPostAssuredSupport.java | 17 ++- ...nnerPostReadByRunnerPostIdAssuredTest.java | 52 +++++++ ...stReadWithLoginedSupporterAssuredTest.java | 119 +++++++++++++++ ...upporterIdAndReviewStatusAssuredTest.java} | 3 +- ...port.java => SupporterAssuredSupport.java} | 4 +- ...upporterReadBySupporterIdAssuredTest.java} | 8 +- ...t.java => SupporterUpdateAssuredTest.java} | 32 ++-- .../runner/RunnerAssuredSupport.java | 60 -------- .../runner/RunnerProfileAssuredReadTest.java | 24 --- ...> MemberReadWithLoginedMemberApiTest.java} | 2 +- ...est.java => RunnerReadByGuestApiTest.java} | 18 +-- .../read/RunnerReadByRunnerIdApiTest.java | 84 +++++++++++ .../RunnerReadWithLoginedRunnerApiTest.java | 80 ++++++++++ ...eApiTest.java => RunnerUpdateApiTest.java} | 11 +- ....java => SupporterReadByGuestApiTest.java} | 6 +- ...iTest.java => SupporterUpdateApiTest.java} | 2 +- ...est.java => RunnerPostReadAllApiTest.java} | 2 +- ...nnerPostReadOfSupporterByGuestApiTest.java | 121 +++++++++++++++ ...erPostReadWithLoginedSupporterApiTest.java | 139 ++++++++++++++++++ .../repository/RunnerPostRepositoryTest.java | 41 ++++++ .../read/RunnerPostRepositoryReadTest.java | 30 ++-- .../service/RunnerPostServiceReadTest.java | 34 ++++- .../fixture/domain/RunnerPostFixture.java | 6 +- 39 files changed, 932 insertions(+), 267 deletions(-) rename backend/baton/src/test/java/touch/baton/assure/feedback/{SupporterFeedbackAssuredCreateTest.java => SupporterFeedbackCreateAssuredTest.java} (86%) rename backend/baton/src/test/java/touch/baton/assure/member/{MemberProfileAssuredSupport.java => MemberAssuredSupport.java} (96%) rename backend/baton/src/test/java/touch/baton/assure/member/{MemberProfileAssuredReadTest.java => MemberReadWithLoginedMemberAssuredTest.java} (81%) rename backend/baton/src/test/java/touch/baton/assure/runner/{RunnerProfileAssuredSupport.java => RunnerAssuredSupport.java} (78%) delete mode 100644 backend/baton/src/test/java/touch/baton/assure/runner/RunnerProfileAssuredReadTest.java create mode 100644 backend/baton/src/test/java/touch/baton/assure/runner/RunnerReadByRunnerIdAssuredTest.java create mode 100644 backend/baton/src/test/java/touch/baton/assure/runner/RunnerReadWithLoginedRunnerAssuredTest.java rename backend/baton/src/test/java/touch/baton/assure/runner/{RunnerProfileAssuredUpdateTest.java => RunnerUpdateAssuredTest.java} (90%) create mode 100644 backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadByRunnerPostIdAssuredTest.java create mode 100644 backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadWithLoginedSupporterAssuredTest.java rename backend/baton/src/test/java/touch/baton/assure/runnerpost/{RunnerPostReadWithGuestAssuredTest.java => RunnerPostReadWithSupporterIdAndReviewStatusAssuredTest.java} (97%) rename backend/baton/src/test/java/touch/baton/assure/supporter/{SupporterProfileAssuredSupport.java => SupporterAssuredSupport.java} (98%) rename backend/baton/src/test/java/touch/baton/assure/supporter/{SupporterProfileAssuredReadTest.java => SupporterReadBySupporterIdAssuredTest.java} (92%) rename backend/baton/src/test/java/touch/baton/assure/supporter/{SupporterProfileAssuredUpdateTest.java => SupporterUpdateAssuredTest.java} (63%) delete mode 100644 backend/baton/src/test/java/touch/baton/controller/runner/RunnerAssuredSupport.java delete mode 100644 backend/baton/src/test/java/touch/baton/controller/runner/RunnerProfileAssuredReadTest.java rename backend/baton/src/test/java/touch/baton/document/profile/member/read/{MemberLoginProfileReadApiTest.java => MemberReadWithLoginedMemberApiTest.java} (97%) rename backend/baton/src/test/java/touch/baton/document/profile/runner/read/{RunnerProfileReadApiTest.java => RunnerReadByGuestApiTest.java} (89%) create mode 100644 backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerReadByRunnerIdApiTest.java create mode 100644 backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerReadWithLoginedRunnerApiTest.java rename backend/baton/src/test/java/touch/baton/document/profile/runner/update/{RunnerProfileUpdateApiTest.java => RunnerUpdateApiTest.java} (88%) rename backend/baton/src/test/java/touch/baton/document/profile/supporter/read/{SupporterProfileReadApiTest.java => SupporterReadByGuestApiTest.java} (96%) rename backend/baton/src/test/java/touch/baton/document/profile/supporter/update/{SupporterProfileUpdateApiTest.java => SupporterUpdateApiTest.java} (98%) rename backend/baton/src/test/java/touch/baton/document/runnerpost/read/{RunnerPostReadApiTest.java => RunnerPostReadAllApiTest.java} (99%) create mode 100644 backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadOfSupporterByGuestApiTest.java create mode 100644 backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadWithLoginedSupporterApiTest.java diff --git a/backend/baton/src/main/java/touch/baton/domain/runnerpost/controller/RunnerPostController.java b/backend/baton/src/main/java/touch/baton/domain/runnerpost/controller/RunnerPostController.java index 3b9acc128..62852903a 100644 --- a/backend/baton/src/main/java/touch/baton/domain/runnerpost/controller/RunnerPostController.java +++ b/backend/baton/src/main/java/touch/baton/domain/runnerpost/controller/RunnerPostController.java @@ -1,6 +1,7 @@ package touch.baton.domain.runnerpost.controller; import jakarta.validation.Valid; +import jakarta.websocket.server.PathParam; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -176,6 +177,29 @@ public ResponseEntity> re return ResponseEntity.ok(PageResponse.from(pageResponse)); } + @GetMapping("/me/supporter") + public ResponseEntity> readRunnerPostsByLoginedSupporterAndReviewStatus( + @PageableDefault(size = 10, page = 1, sort = "createdAt", direction = DESC) final Pageable pageable, + @AuthSupporterPrincipal final Supporter supporter, + @PathParam("reviewStatus") final ReviewStatus reviewStatus + ) { + final Page pageRunnerPosts = runnerPostService.readRunnerPostsBySupporterIdAndReviewStatus(pageable, supporter.getId(), reviewStatus); + final List foundRunnerPosts = pageRunnerPosts.getContent(); + final List applicantCounts = collectApplicantCounts(pageRunnerPosts); + final List responses = IntStream.range(0, foundRunnerPosts.size()) + .mapToObj(index -> { + final RunnerPost foundRunnerPost = foundRunnerPosts.get(index); + final Long applicantCount = applicantCounts.get(index); + + return RunnerPostResponse.ReferencedBySupporter.of(foundRunnerPost, applicantCount); + }).toList(); + + final Page pageResponse + = new PageImpl<>(responses, pageable, pageRunnerPosts.getTotalPages()); + + return ResponseEntity.ok(PageResponse.from(pageResponse)); + } + private List collectApplicantCounts(final Page pageRunnerPosts) { final List runnerPostIds = pageRunnerPosts.stream() .map(RunnerPost::getId) diff --git a/backend/baton/src/main/java/touch/baton/domain/runnerpost/controller/response/RunnerPostReadResponses.java b/backend/baton/src/main/java/touch/baton/domain/runnerpost/controller/response/RunnerPostReadResponses.java index fbf200187..b2b686fa2 100644 --- a/backend/baton/src/main/java/touch/baton/domain/runnerpost/controller/response/RunnerPostReadResponses.java +++ b/backend/baton/src/main/java/touch/baton/domain/runnerpost/controller/response/RunnerPostReadResponses.java @@ -10,4 +10,11 @@ public static NoFiltering from(final List data) { return new NoFiltering(data); } } + + public record LoginedSupporter(List data) { + + public static LoginedSupporter from(final List data) { + return new LoginedSupporter(data); + } + } } diff --git a/backend/baton/src/main/java/touch/baton/domain/runnerpost/controller/response/RunnerPostResponse.java b/backend/baton/src/main/java/touch/baton/domain/runnerpost/controller/response/RunnerPostResponse.java index 7e5ed0568..42d90f82b 100644 --- a/backend/baton/src/main/java/touch/baton/domain/runnerpost/controller/response/RunnerPostResponse.java +++ b/backend/baton/src/main/java/touch/baton/domain/runnerpost/controller/response/RunnerPostResponse.java @@ -52,6 +52,7 @@ public record DetailVersionTest(Long runnerPostId, boolean isOwner, List tags ) { + public static DetailVersionTest ofVersionTest(final RunnerPost runnerPost, final boolean isOwner) { return new DetailVersionTest( runnerPost.getId(), @@ -91,13 +92,34 @@ public static Simple from(final RunnerPost runnerPost) { } } + public record LoginedSupporter(Long runnerPostId, + String title, + LocalDateTime deadline, + List tags, + int watchedCount, + int applicantCount + + ) { + + public static LoginedSupporter from(final RunnerPost runnerPost, final int applicantCount) { + return new LoginedSupporter( + runnerPost.getId(), + runnerPost.getTitle().getValue(), + runnerPost.getDeadline().getValue(), + convertToTags(runnerPost), + runnerPost.getWatchedCount().getValue(), + applicantCount + ); + } + } + public record Mine(Long runnerPostId, String title, LocalDateTime deadline, List tags, String reviewStatus - ) { + public static Mine from(final RunnerPost runnerPost) { return new Mine( runnerPost.getId(), diff --git a/backend/baton/src/main/java/touch/baton/domain/runnerpost/repository/RunnerPostRepository.java b/backend/baton/src/main/java/touch/baton/domain/runnerpost/repository/RunnerPostRepository.java index 51b7c8c08..339316ff5 100644 --- a/backend/baton/src/main/java/touch/baton/domain/runnerpost/repository/RunnerPostRepository.java +++ b/backend/baton/src/main/java/touch/baton/domain/runnerpost/repository/RunnerPostRepository.java @@ -5,7 +5,6 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import touch.baton.domain.common.vo.Title; import touch.baton.domain.runnerpost.RunnerPost; import touch.baton.domain.runnerpost.vo.ReviewStatus; @@ -37,7 +36,14 @@ Page findBySupporterIdAndReviewStatus(final Pageable pageable, @Param("supporterId") final Long supporterId, @Param("reviewStatus") final ReviewStatus reviewStatus); - List readBySupporterId(Long supporterId); - - Optional readByTitle(Title title); + @Query(""" + select rp + from RunnerPost rp + join fetch SupporterRunnerPost srp on srp.runnerPost.id = rp.id + where srp.supporter.id = :supporterId + and rp.reviewStatus = :reviewStatus + """) + Page joinSupporterRunnerPostBySupporterIdAndReviewStatus(final Pageable pageable, + @Param("supporterId") final Long supporterId, + @Param("reviewStatus") final ReviewStatus reviewStatus); } diff --git a/backend/baton/src/main/java/touch/baton/domain/runnerpost/service/RunnerPostService.java b/backend/baton/src/main/java/touch/baton/domain/runnerpost/service/RunnerPostService.java index b1cd20afa..2de45ab69 100644 --- a/backend/baton/src/main/java/touch/baton/domain/runnerpost/service/RunnerPostService.java +++ b/backend/baton/src/main/java/touch/baton/domain/runnerpost/service/RunnerPostService.java @@ -237,6 +237,9 @@ public Page readRunnerPostsBySupporterIdAndReviewStatus(final Pageab final Long supporterId, final ReviewStatus reviewStatus ) { + if (reviewStatus.isSameAsNotStarted()) { + return runnerPostRepository.joinSupporterRunnerPostBySupporterIdAndReviewStatus(pageable, supporterId, reviewStatus); + } return runnerPostRepository.findBySupporterIdAndReviewStatus(pageable, supporterId, reviewStatus); } diff --git a/backend/baton/src/main/java/touch/baton/domain/runnerpost/vo/ReviewStatus.java b/backend/baton/src/main/java/touch/baton/domain/runnerpost/vo/ReviewStatus.java index b0d772817..da8916bb6 100644 --- a/backend/baton/src/main/java/touch/baton/domain/runnerpost/vo/ReviewStatus.java +++ b/backend/baton/src/main/java/touch/baton/domain/runnerpost/vo/ReviewStatus.java @@ -17,6 +17,10 @@ public boolean isSame(final ReviewStatus reviewStatus) { return this == reviewStatus; } + public boolean isSameAsNotStarted() { + return this == NOT_STARTED; + } + public boolean isNotSameAsNotStarted() { return this != NOT_STARTED; } diff --git a/backend/baton/src/test/java/touch/baton/assure/common/AssuredSupport.java b/backend/baton/src/test/java/touch/baton/assure/common/AssuredSupport.java index e5f0da8e1..a9e6e61c8 100644 --- a/backend/baton/src/test/java/touch/baton/assure/common/AssuredSupport.java +++ b/backend/baton/src/test/java/touch/baton/assure/common/AssuredSupport.java @@ -50,15 +50,10 @@ public static ExtractableResponse post(final String uri, .extract(); } - public static ExtractableResponse get(final String uri, - final String pathParamName, - final Long id, - final String accessToken - ) { + public static ExtractableResponse get(final String uri, final String accessToken) { return RestAssured .given().log().ifValidationFails() .auth().preemptive().oauth2(accessToken) - .pathParam(pathParamName, id) .when().log().ifValidationFails() .get(uri) .then().log().ifError() @@ -75,10 +70,15 @@ public static ExtractableResponse get(final String uri, final String p .extract(); } - public static ExtractableResponse get(final String uri, final String accessToken) { + public static ExtractableResponse get(final String uri, + final String pathParamName, + final Long id, + final String accessToken + ) { return RestAssured .given().log().ifValidationFails() .auth().preemptive().oauth2(accessToken) + .pathParam(pathParamName, id) .when().log().ifValidationFails() .get(uri) .then().log().ifError() @@ -97,14 +97,14 @@ public static ExtractableResponse get(final String uri, final Map patch(final String uri, final String accessToken, final Object params) { + public static ExtractableResponse get(final String uri, final String accessToken, final Map queryParams) { return RestAssured .given().log().ifValidationFails() .auth().preemptive().oauth2(accessToken) .contentType(APPLICATION_JSON_VALUE) - .body(params) + .queryParams(queryParams) .when().log().ifValidationFails() - .patch(uri) + .get(uri) .then().log().ifError() .extract(); } @@ -127,6 +127,19 @@ public static ExtractableResponse patch(final String uri, .extract(); } + + public static ExtractableResponse patch(final String uri, final String accessToken, final Object requestBody) { + return RestAssured + .given().log().ifValidationFails() + .auth().preemptive().oauth2(accessToken) + .contentType(APPLICATION_JSON_VALUE) + .body(requestBody) + .when().log().ifValidationFails() + .patch(uri) + .then().log().ifError() + .extract(); + } + public static ExtractableResponse patch(final String uri, final String pathParamName, final Long id, final String accessToken) { return RestAssured .given().log().ifValidationFails() diff --git a/backend/baton/src/test/java/touch/baton/assure/feedback/SupporterFeedbackAssuredSupport.java b/backend/baton/src/test/java/touch/baton/assure/feedback/SupporterFeedbackAssuredSupport.java index eb8b6f243..d799dcc83 100644 --- a/backend/baton/src/test/java/touch/baton/assure/feedback/SupporterFeedbackAssuredSupport.java +++ b/backend/baton/src/test/java/touch/baton/assure/feedback/SupporterFeedbackAssuredSupport.java @@ -9,6 +9,7 @@ import static org.assertj.core.api.SoftAssertions.assertSoftly; +@SuppressWarnings("NonAsciiCharacters") public class SupporterFeedbackAssuredSupport { private SupporterFeedbackAssuredSupport() { diff --git a/backend/baton/src/test/java/touch/baton/assure/feedback/SupporterFeedbackAssuredCreateTest.java b/backend/baton/src/test/java/touch/baton/assure/feedback/SupporterFeedbackCreateAssuredTest.java similarity index 86% rename from backend/baton/src/test/java/touch/baton/assure/feedback/SupporterFeedbackAssuredCreateTest.java rename to backend/baton/src/test/java/touch/baton/assure/feedback/SupporterFeedbackCreateAssuredTest.java index 33d707949..66a5222e9 100644 --- a/backend/baton/src/test/java/touch/baton/assure/feedback/SupporterFeedbackAssuredCreateTest.java +++ b/backend/baton/src/test/java/touch/baton/assure/feedback/SupporterFeedbackCreateAssuredTest.java @@ -24,7 +24,7 @@ import static touch.baton.fixture.vo.ReviewCountFixture.reviewCount; @SuppressWarnings("NonAsciiCharacters") -class SupporterFeedbackAssuredCreateTest extends AssuredTestConfig { +class SupporterFeedbackCreateAssuredTest extends AssuredTestConfig { // TODO: 2023/08/03 로그인 기능 테스트 추가 @Disabled @@ -41,7 +41,10 @@ class SupporterFeedbackAssuredCreateTest extends AssuredTestConfig { // when, then SupporterFeedbackAssuredSupport - .클라이언트_요청().서포터_피드백을_등록한다(request) - .서버_응답().서포터_피드백_등록_성공을_검증한다(new HttpStatusAndLocationHeader(CREATED, "/api/v1/feedback/supporter")); + .클라이언트_요청() + .서포터_피드백을_등록한다(request) + + .서버_응답() + .서포터_피드백_등록_성공을_검증한다(new HttpStatusAndLocationHeader(CREATED, "/api/v1/feedback/supporter")); } } diff --git a/backend/baton/src/test/java/touch/baton/assure/member/MemberProfileAssuredSupport.java b/backend/baton/src/test/java/touch/baton/assure/member/MemberAssuredSupport.java similarity index 96% rename from backend/baton/src/test/java/touch/baton/assure/member/MemberProfileAssuredSupport.java rename to backend/baton/src/test/java/touch/baton/assure/member/MemberAssuredSupport.java index ae4dbff76..3dd5d0062 100644 --- a/backend/baton/src/test/java/touch/baton/assure/member/MemberProfileAssuredSupport.java +++ b/backend/baton/src/test/java/touch/baton/assure/member/MemberAssuredSupport.java @@ -9,9 +9,9 @@ import static org.assertj.core.api.SoftAssertions.assertSoftly; @SuppressWarnings("NonAsciiCharacters") -public class MemberProfileAssuredSupport { +public class MemberAssuredSupport { - private MemberProfileAssuredSupport() { + private MemberAssuredSupport() { } public static MemberClientRequestBuilder 클라이언트_요청() { diff --git a/backend/baton/src/test/java/touch/baton/assure/member/MemberProfileAssuredReadTest.java b/backend/baton/src/test/java/touch/baton/assure/member/MemberReadWithLoginedMemberAssuredTest.java similarity index 81% rename from backend/baton/src/test/java/touch/baton/assure/member/MemberProfileAssuredReadTest.java rename to backend/baton/src/test/java/touch/baton/assure/member/MemberReadWithLoginedMemberAssuredTest.java index 3598ea69f..21be39d16 100644 --- a/backend/baton/src/test/java/touch/baton/assure/member/MemberProfileAssuredReadTest.java +++ b/backend/baton/src/test/java/touch/baton/assure/member/MemberReadWithLoginedMemberAssuredTest.java @@ -5,10 +5,10 @@ import touch.baton.domain.member.Member; import touch.baton.fixture.domain.MemberFixture; -import static touch.baton.assure.member.MemberProfileAssuredSupport.로그인한_사용자_프로필_응답; +import static touch.baton.assure.member.MemberAssuredSupport.로그인한_사용자_프로필_응답; @SuppressWarnings("NonAsciiCharacters") -public class MemberProfileAssuredReadTest extends AssuredTestConfig { +public class MemberReadWithLoginedMemberAssuredTest extends AssuredTestConfig { @Test void 로그인_한_맴버_프로필을_조회한다() { @@ -16,7 +16,7 @@ public class MemberProfileAssuredReadTest extends AssuredTestConfig { final Member 사용자_디투 = memberRepository.save(MemberFixture.createWithSocialId(디투_소셜_id)); final String 디투_액세스_토큰 = login(디투_소셜_id); - MemberProfileAssuredSupport + MemberAssuredSupport .클라이언트_요청() .로그인_한다(디투_액세스_토큰) .사용자_본인_프로필을_가지고_있는_토큰으로_조회한다() diff --git a/backend/baton/src/test/java/touch/baton/assure/runner/RunnerProfileAssuredSupport.java b/backend/baton/src/test/java/touch/baton/assure/runner/RunnerAssuredSupport.java similarity index 78% rename from backend/baton/src/test/java/touch/baton/assure/runner/RunnerProfileAssuredSupport.java rename to backend/baton/src/test/java/touch/baton/assure/runner/RunnerAssuredSupport.java index b40bc60e1..d2708e749 100644 --- a/backend/baton/src/test/java/touch/baton/assure/runner/RunnerProfileAssuredSupport.java +++ b/backend/baton/src/test/java/touch/baton/assure/runner/RunnerAssuredSupport.java @@ -13,60 +13,61 @@ import static org.assertj.core.api.SoftAssertions.assertSoftly; -public class RunnerProfileAssuredSupport { +@SuppressWarnings("NonAsciiCharacters") +public class RunnerAssuredSupport { - private RunnerProfileAssuredSupport() { + private RunnerAssuredSupport() { } - public static RunnerProfileClientRequestBuilder 클라이언트_요청() { - return new RunnerProfileClientRequestBuilder(); + public static RunnerClientRequestBuilder 클라이언트_요청() { + return new RunnerClientRequestBuilder(); } public static RunnerResponse.MyProfile 러너_본인_프로필_응답(final Runner 러너) { return RunnerResponse.MyProfile.from(러너); } - public static class RunnerProfileClientRequestBuilder { + public static class RunnerClientRequestBuilder { private ExtractableResponse response; private String accessToken; - public RunnerProfileClientRequestBuilder 토큰으로_로그인한다(final String 토큰) { + public RunnerClientRequestBuilder 토큰으로_로그인한다(final String 토큰) { this.accessToken = 토큰; return this; } - public RunnerProfileClientRequestBuilder 러너_본인_프로필을_가지고_있는_토큰으로_조회한다() { + public RunnerClientRequestBuilder 러너_본인_프로필을_가지고_있는_토큰으로_조회한다() { response = AssuredSupport.get("/api/v1/profile/runner/me", accessToken); return this; } - public RunnerProfileClientRequestBuilder 러너_피드백을_상세_조회한다(final Long 러너_식별자) { + public RunnerClientRequestBuilder 러너_프로필을_상세_조회한다(final Long 러너_식별자) { response = AssuredSupport.get("/api/v1/profile/runner/{runnerId}", "runnerId", 러너_식별자); return this; } - public RunnerProfileServerResponseBuilder 서버_응답() { - return new RunnerProfileServerResponseBuilder(response); + public RunnerServerResponseBuilder 서버_응답() { + return new RunnerServerResponseBuilder(response); } - public RunnerProfileClientRequestBuilder 러너_본인_프로필을_수정한다(final RunnerUpdateRequest 러너_업데이트_요청) { + public RunnerClientRequestBuilder 러너_본인_프로필을_수정한다(final RunnerUpdateRequest 러너_업데이트_요청) { response = AssuredSupport.patch("/api/v1/profile/runner/me", accessToken, 러너_업데이트_요청); return this; } } - public static class RunnerProfileServerResponseBuilder { + public static class RunnerServerResponseBuilder { private final ExtractableResponse response; - public RunnerProfileServerResponseBuilder(final ExtractableResponse response) { + public RunnerServerResponseBuilder(final ExtractableResponse response) { this.response = response; } - public static RunnerProfileClientRequestBuilder 클라이언트_요청() { - return new RunnerProfileClientRequestBuilder(); + public static RunnerClientRequestBuilder 클라이언트_요청() { + return new RunnerClientRequestBuilder(); } public void 러너_본인_프로필_조회_성공을_검증한다(final RunnerResponse.MyProfile 러너_본인_프로필_응답) { diff --git a/backend/baton/src/test/java/touch/baton/assure/runner/RunnerProfileAssuredReadTest.java b/backend/baton/src/test/java/touch/baton/assure/runner/RunnerProfileAssuredReadTest.java deleted file mode 100644 index 9cdd1ec70..000000000 --- a/backend/baton/src/test/java/touch/baton/assure/runner/RunnerProfileAssuredReadTest.java +++ /dev/null @@ -1,56 +0,0 @@ -package touch.baton.assure.runner; - -import org.junit.jupiter.api.Test; -import touch.baton.config.AssuredTestConfig; -import touch.baton.domain.member.Member; -import touch.baton.domain.runner.Runner; -import touch.baton.domain.runner.controller.response.RunnerProfileResponse; -import touch.baton.domain.technicaltag.TechnicalTag; -import touch.baton.fixture.domain.MemberFixture; -import touch.baton.fixture.domain.RunnerFixture; -import touch.baton.fixture.domain.TechnicalTagFixture; - -import java.util.List; - -import static touch.baton.assure.runner.RunnerProfileAssuredSupport.러너_본인_프로필_응답; -import static touch.baton.fixture.vo.IntroductionFixture.introduction; - -@SuppressWarnings("NonAsciiCharacters") -class RunnerProfileAssuredReadTest extends AssuredTestConfig { - - @Test - void 러너_본인_프로필을_가지고_있는_토큰으로_조회에_성공한다() { - final Member 사용자_헤나 = memberRepository.save(MemberFixture.createHyena()); - final Runner 러너_헤나 = runnerRepository.save(RunnerFixture.createRunner(introduction("안녕하세요"), 사용자_헤나)); - final String 로그인용_토큰 = login(사용자_헤나.getSocialId().getValue()); - - RunnerProfileAssuredSupport - .클라이언트_요청() - .토큰으로_로그인한다(로그인용_토큰) - .러너_본인_프로필을_가지고_있는_토큰으로_조회한다() - - .서버_응답() - .러너_본인_프로필_조회_성공을_검증한다(러너_본인_프로필_응답(러너_헤나)); - } - - @Test - void 러너_프로필_조회에_성공한다() { - // given - final Member 사용자_에단 = memberRepository.save(MemberFixture.createEthan()); - final TechnicalTag 자바_태그 = technicalTagRepository.save(TechnicalTagFixture.createJava()); - final TechnicalTag 리액트_태그 = technicalTagRepository.save(TechnicalTagFixture.createReact()); - final Runner 러너_에단 = runnerRepository.save(RunnerFixture.createRunner(사용자_에단, List.of(자바_태그, 리액트_태그))); - - // when, then - RunnerProfileAssuredSupport - .클라이언트_요청().러너_피드백을_상세_조회한다(러너_에단.getId()) - .서버_응답().러너_프로필_상세_조회를_검증한다(new RunnerProfileResponse.Detail( - 1L, - "에단", - "https://", - "https://github.com/", - "안녕하세요.", - "우아한테크코스 5기 백엔드", - List.of("Java", "React"))); - } -} diff --git a/backend/baton/src/test/java/touch/baton/assure/runner/RunnerReadByRunnerIdAssuredTest.java b/backend/baton/src/test/java/touch/baton/assure/runner/RunnerReadByRunnerIdAssuredTest.java new file mode 100644 index 000000000..e8c0e16ac --- /dev/null +++ b/backend/baton/src/test/java/touch/baton/assure/runner/RunnerReadByRunnerIdAssuredTest.java @@ -0,0 +1,42 @@ +package touch.baton.assure.runner; + +import org.junit.jupiter.api.Test; +import touch.baton.config.AssuredTestConfig; +import touch.baton.domain.member.Member; +import touch.baton.domain.runner.Runner; +import touch.baton.domain.runner.controller.response.RunnerProfileResponse; +import touch.baton.domain.technicaltag.TechnicalTag; +import touch.baton.fixture.domain.MemberFixture; +import touch.baton.fixture.domain.RunnerFixture; +import touch.baton.fixture.domain.TechnicalTagFixture; + +import java.util.List; + +@SuppressWarnings("NonAsciiCharacters") +class RunnerReadByRunnerIdAssuredTest extends AssuredTestConfig { + + @Test + void 러너_프로필_조회에_성공한다() { + // given + final Member 사용자_에단 = memberRepository.save(MemberFixture.createEthan()); + final TechnicalTag 자바_태그 = technicalTagRepository.save(TechnicalTagFixture.createJava()); + final TechnicalTag 리액트_태그 = technicalTagRepository.save(TechnicalTagFixture.createReact()); + final Runner 러너_에단 = runnerRepository.save(RunnerFixture.createRunner(사용자_에단, List.of(자바_태그, 리액트_태그))); + final RunnerProfileResponse.Detail 러너_프로필_조회_응답 = new RunnerProfileResponse.Detail( + 1L, + "에단", + "https://", + "https://github.com/", + "안녕하세요.", + "우아한테크코스 5기 백엔드", + List.of("Java", "React")); + + // when, then + RunnerAssuredSupport + .클라이언트_요청() + .러너_프로필을_상세_조회한다(러너_에단.getId()) + + .서버_응답() + .러너_프로필_상세_조회를_검증한다(러너_프로필_조회_응답); + } +} diff --git a/backend/baton/src/test/java/touch/baton/assure/runner/RunnerReadWithLoginedRunnerAssuredTest.java b/backend/baton/src/test/java/touch/baton/assure/runner/RunnerReadWithLoginedRunnerAssuredTest.java new file mode 100644 index 000000000..1735d21a4 --- /dev/null +++ b/backend/baton/src/test/java/touch/baton/assure/runner/RunnerReadWithLoginedRunnerAssuredTest.java @@ -0,0 +1,30 @@ +package touch.baton.assure.runner; + +import org.junit.jupiter.api.Test; +import touch.baton.config.AssuredTestConfig; +import touch.baton.domain.member.Member; +import touch.baton.domain.runner.Runner; +import touch.baton.fixture.domain.MemberFixture; +import touch.baton.fixture.domain.RunnerFixture; + +import static touch.baton.assure.runner.RunnerAssuredSupport.러너_본인_프로필_응답; +import static touch.baton.fixture.vo.IntroductionFixture.introduction; + +@SuppressWarnings("NonAsciiCharacters") +class RunnerReadWithLoginedRunnerAssuredTest extends AssuredTestConfig { + + @Test + void 러너_본인_프로필을_가지고_있는_토큰으로_조회에_성공한다() { + final Member 사용자_헤나 = memberRepository.save(MemberFixture.createHyena()); + final Runner 러너_헤나 = runnerRepository.save(RunnerFixture.createRunner(introduction("안녕하세요"), 사용자_헤나)); + final String 로그인용_토큰 = login(사용자_헤나.getSocialId().getValue()); + + RunnerAssuredSupport + .클라이언트_요청() + .토큰으로_로그인한다(로그인용_토큰) + .러너_본인_프로필을_가지고_있는_토큰으로_조회한다() + + .서버_응답() + .러너_본인_프로필_조회_성공을_검증한다(러너_본인_프로필_응답(러너_헤나)); + } +} diff --git a/backend/baton/src/test/java/touch/baton/assure/runner/RunnerProfileAssuredUpdateTest.java b/backend/baton/src/test/java/touch/baton/assure/runner/RunnerUpdateAssuredTest.java similarity index 90% rename from backend/baton/src/test/java/touch/baton/assure/runner/RunnerProfileAssuredUpdateTest.java rename to backend/baton/src/test/java/touch/baton/assure/runner/RunnerUpdateAssuredTest.java index 15869810f..6b3c31b31 100644 --- a/backend/baton/src/test/java/touch/baton/assure/runner/RunnerProfileAssuredUpdateTest.java +++ b/backend/baton/src/test/java/touch/baton/assure/runner/RunnerUpdateAssuredTest.java @@ -12,12 +12,10 @@ import java.util.List; import static org.springframework.http.HttpStatus.NO_CONTENT; -import static touch.baton.domain.common.exception.ClientErrorCode.COMPANY_IS_NULL; -import static touch.baton.domain.common.exception.ClientErrorCode.NAME_IS_NULL; -import static touch.baton.domain.common.exception.ClientErrorCode.RUNNER_TECHNICAL_TAGS_ARE_NULL; +import static touch.baton.domain.common.exception.ClientErrorCode.*; @SuppressWarnings("NonAsciiCharacters") -public class RunnerProfileAssuredUpdateTest extends AssuredTestConfig { +public class RunnerUpdateAssuredTest extends AssuredTestConfig { private String 디투_액세스_토큰; @@ -35,7 +33,7 @@ void setUp() { void 러너_정보를_수정한다() { final RunnerUpdateRequest 러너_업데이트_요청 = new RunnerUpdateRequest("업데이트된 이름", "업데이트된 소속", "업데이트된 자기소개", List.of("Java", "React")); - RunnerProfileAssuredSupport + RunnerAssuredSupport .클라이언트_요청() .토큰으로_로그인한다(디투_액세스_토큰) .러너_본인_프로필을_수정한다(러너_업데이트_요청) @@ -48,7 +46,7 @@ void setUp() { void 러너_정보_수정_시에_이름이_없으면_예외가_발생한다() { final RunnerUpdateRequest 러너_업데이트_요청 = new RunnerUpdateRequest(null, "업데이트된 소속", "업데이트된 자기소개", List.of("Java", "React")); - RunnerProfileAssuredSupport + RunnerAssuredSupport .클라이언트_요청() .토큰으로_로그인한다(디투_액세스_토큰) .러너_본인_프로필을_수정한다(러너_업데이트_요청) @@ -61,7 +59,7 @@ void setUp() { void 서포터_정보_수정_시에_소속이_없으면_예외가_발생한다() { final RunnerUpdateRequest 러너_업데이트_요청 = new RunnerUpdateRequest("업데이트된 이름", null, "업데이트된 자기소개", List.of("Java", "React")); - RunnerProfileAssuredSupport + RunnerAssuredSupport .클라이언트_요청() .토큰으로_로그인한다(디투_액세스_토큰) .러너_본인_프로필을_수정한다(러너_업데이트_요청) @@ -74,7 +72,7 @@ void setUp() { void 러너_정보_수정_시에_소개글이_없어도_된다() { final RunnerUpdateRequest 러너_업데이트_요청 = new RunnerUpdateRequest("업데이트된 이름", "업데이트된 소속", null, List.of("Java", "React")); - RunnerProfileAssuredSupport + RunnerAssuredSupport .클라이언트_요청() .토큰으로_로그인한다(디투_액세스_토큰) .러너_본인_프로필을_수정한다(러너_업데이트_요청) @@ -87,7 +85,7 @@ void setUp() { void 러너_정보_수정_시에_기술_태그가_없으면_예외가_발생한다() { final RunnerUpdateRequest 러너_업데이트_요청 = new RunnerUpdateRequest("업데이트된 이름", "업데이트된 소속", "업데이트된 자기소개", null); - RunnerProfileAssuredSupport + RunnerAssuredSupport .클라이언트_요청() .토큰으로_로그인한다(디투_액세스_토큰) .러너_본인_프로필을_수정한다(러너_업데이트_요청) diff --git a/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostAssuredSupport.java b/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostAssuredSupport.java index 29e1764d8..e3cfea641 100644 --- a/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostAssuredSupport.java +++ b/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostAssuredSupport.java @@ -87,12 +87,12 @@ public static class RunnerPostClientRequestBuilder { } public RunnerPostClientRequestBuilder 서포터와_연관된_러너_게시글_페이징을_조회한다(final Long 서포터_식별자값, - final ReviewStatus 리뷰_상태, + final ReviewStatus 리뷰_진행_상태, final Pageable 페이징_정보 ) { final Map queryParams = Map.of( "supporterId", 서포터_식별자값, - "reviewStatus", 리뷰_상태, + "reviewStatus", 리뷰_진행_상태, "size", 페이징_정보.getPageSize(), "page", 페이징_정보.getPageNumber() ); @@ -122,6 +122,19 @@ public static class RunnerPostClientRequestBuilder { return this; } + public RunnerPostClientRequestBuilder 로그인한_서포터의_러너_게시글_페이징을_조회한다(final ReviewStatus 리뷰_진행_상태, + final Pageable 페이징_정보 + ) { + final Map queryParams = Map.of( + "reviewStatus", 리뷰_진행_상태, + "size", 페이징_정보.getPageSize(), + "page", 페이징_정보.getPageNumber() + ); + + response = AssuredSupport.get("/api/v1/posts/runner/me/supporter", accessToken, queryParams); + return this; + } + public RunnerPostServerResponseBuilder 서버_응답() { return new RunnerPostServerResponseBuilder(response); } diff --git a/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadByRunnerPostIdAssuredTest.java b/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadByRunnerPostIdAssuredTest.java new file mode 100644 index 000000000..15d777dbf --- /dev/null +++ b/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadByRunnerPostIdAssuredTest.java @@ -0,0 +1,52 @@ +package touch.baton.assure.runnerpost; + +import org.junit.jupiter.api.Test; +import touch.baton.config.AssuredTestConfig; +import touch.baton.domain.member.Member; +import touch.baton.domain.runner.Runner; +import touch.baton.domain.runner.controller.response.RunnerResponse; +import touch.baton.domain.runnerpost.RunnerPost; +import touch.baton.domain.runnerpost.controller.response.RunnerPostResponse; +import touch.baton.domain.runnerpost.vo.ReviewStatus; +import touch.baton.fixture.domain.MemberFixture; +import touch.baton.fixture.domain.RunnerFixture; +import touch.baton.fixture.domain.RunnerPostFixture; + +import java.time.LocalDateTime; +import java.util.ArrayList; + +import static touch.baton.fixture.vo.DeadlineFixture.deadline; +import static touch.baton.fixture.vo.IntroductionFixture.introduction; +import static touch.baton.fixture.vo.WatchedCountFixture.watchedCount; + +@SuppressWarnings("NonAsciiCharacters") +class RunnerPostReadByRunnerPostIdAssuredTest extends AssuredTestConfig { + + @Test + void 러너의_게시글_식별자값으로_러너_게시글_상세_정보_조회에_성공한다() { + final Member 사용자_헤나 = memberRepository.save(MemberFixture.createHyena()); + final Runner 러너_헤나 = runnerRepository.save(RunnerFixture.createRunner(introduction("안녕하세요"), 사용자_헤나)); + final RunnerPost 러너_게시글 = runnerPostRepository.save(RunnerPostFixture.create(러너_헤나, deadline(LocalDateTime.now().plusHours(100)))); + final String 로그인용_토큰 = login(사용자_헤나.getSocialId().getValue()); + + RunnerPostAssuredSupport + .클라이언트_요청() + .토큰으로_로그인한다(로그인용_토큰) + .러너_게시글_식별자값으로_러너_게시글을_조회한다(러너_게시글.getId()) + + .서버_응답() + .러너_게시글_단건_조회_성공을_검증한다(new RunnerPostResponse.Detail( + 러너_게시글.getId(), + 러너_게시글.getTitle().getValue(), + 러너_게시글.getContents().getValue(), + 러너_게시글.getPullRequestUrl().getValue(), + 러너_게시글.getDeadline().getValue(), + watchedCount(1).getValue(), + 0L, + ReviewStatus.NOT_STARTED, + true, + new ArrayList<>(), + RunnerResponse.Detail.from(러너_헤나) + )); + } +} diff --git a/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadWithLoginedSupporterAssuredTest.java b/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadWithLoginedSupporterAssuredTest.java new file mode 100644 index 000000000..8ec155ff3 --- /dev/null +++ b/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadWithLoginedSupporterAssuredTest.java @@ -0,0 +1,119 @@ +package touch.baton.assure.runnerpost; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.PageRequest; +import touch.baton.config.AssuredTestConfig; +import touch.baton.domain.common.response.PageResponse; +import touch.baton.domain.member.Member; +import touch.baton.domain.runner.Runner; +import touch.baton.domain.runnerpost.RunnerPost; +import touch.baton.domain.runnerpost.controller.response.RunnerPostResponse; +import touch.baton.domain.runnerpost.vo.ReviewStatus; +import touch.baton.domain.supporter.Supporter; +import touch.baton.fixture.domain.MemberFixture; +import touch.baton.fixture.domain.RunnerFixture; +import touch.baton.fixture.domain.RunnerPostFixture; +import touch.baton.fixture.domain.SupporterFixture; +import touch.baton.fixture.domain.SupporterRunnerPostFixture; + +import java.time.LocalDateTime; +import java.util.List; + +import static touch.baton.assure.runnerpost.RunnerPostAssuredSupport.서포터가_리뷰_완료한_러너_게시글_응답; +import static touch.baton.fixture.vo.DeadlineFixture.deadline; + +@SuppressWarnings("NonAsciiCharacters") +public class RunnerPostReadWithLoginedSupporterAssuredTest extends AssuredTestConfig { + + private Supporter 로그인된_서포터; + private String 로그인용_토큰; + private final PageRequest 페이징_정보 = PageRequest.of(1, 10); + private RunnerPost 대기중인_게시글; + private RunnerPost 리뷰중인_게시글; + private RunnerPost 완료된_게시글; + + @BeforeEach + void setUp() { + final Member 로그인된_사용자 = memberRepository.save(MemberFixture.createDitoo()); + 로그인된_서포터 = supporterRepository.save(SupporterFixture.create(로그인된_사용자)); + 로그인용_토큰 = login(로그인된_사용자.getSocialId().getValue()); + 로그인된_서포터의_러너_게시글을_모든_리뷰_상태로_저장한다(로그인된_서포터); + } + + private void 로그인된_서포터의_러너_게시글을_모든_리뷰_상태로_저장한다(final Supporter 로그인된_서포터) { + final Member 사용자_누군가 = memberRepository.save(MemberFixture.createEthan()); + final Runner 러너_누군가 = runnerRepository.save(RunnerFixture.createRunner(사용자_누군가)); + 대기중인_게시글 = runnerPostRepository.save(RunnerPostFixture.create( + 러너_누군가, + null, + deadline(LocalDateTime.now().plusHours(100)), + ReviewStatus.NOT_STARTED + )); + supporterRunnerPostRepository.save(SupporterRunnerPostFixture.create(대기중인_게시글, 로그인된_서포터)); + + 리뷰중인_게시글 = runnerPostRepository.save(RunnerPostFixture.create( + 러너_누군가, + 로그인된_서포터, + deadline(LocalDateTime.now().plusHours(100)), + ReviewStatus.IN_PROGRESS + )); + supporterRunnerPostRepository.save(SupporterRunnerPostFixture.create(리뷰중인_게시글, 로그인된_서포터)); + + 완료된_게시글 = runnerPostRepository.save(RunnerPostFixture.create( + 러너_누군가, + 로그인된_서포터, + deadline(LocalDateTime.now().plusHours(100)), + ReviewStatus.DONE + )); + supporterRunnerPostRepository.save(SupporterRunnerPostFixture.create(완료된_게시글, 로그인된_서포터)); + } + + @Test + void 로그인된_서포터의_대기중인_러너_게시글_목록_조회에_성공한다() { + final RunnerPostResponse.ReferencedBySupporter 서포터가_지원한_러너_게시글_응답 + = RunnerPostResponse.ReferencedBySupporter.of(대기중인_게시글, 1); + final PageResponse 페이징된_서포터가_지원한_러너_게시글_응답 + = 서포터가_리뷰_완료한_러너_게시글_응답(페이징_정보, List.of(서포터가_지원한_러너_게시글_응답)); + + RunnerPostAssuredSupport + .클라이언트_요청() + .토큰으로_로그인한다(로그인용_토큰) + .로그인한_서포터의_러너_게시글_페이징을_조회한다(ReviewStatus.NOT_STARTED, 페이징_정보) + + .서버_응답() + .서포터와_연관된_러너_게시글_페이징_조회_성공을_검증한다(페이징된_서포터가_지원한_러너_게시글_응답); + } + + @Test + void 로그인된_서포터의_진행중인_러너_게시글_목록_조회에_성공한다() { + final RunnerPostResponse.ReferencedBySupporter 서포터가_리뷰중인_러너_게시글_응답 + = RunnerPostResponse.ReferencedBySupporter.of(리뷰중인_게시글, 1); + final PageResponse 페이징된_서포터가_리뷰중인_러너_게시글_응답 + = 서포터가_리뷰_완료한_러너_게시글_응답(페이징_정보, List.of(서포터가_리뷰중인_러너_게시글_응답)); + + RunnerPostAssuredSupport + .클라이언트_요청() + .토큰으로_로그인한다(로그인용_토큰) + .로그인한_서포터의_러너_게시글_페이징을_조회한다(ReviewStatus.IN_PROGRESS, 페이징_정보) + + .서버_응답() + .서포터와_연관된_러너_게시글_페이징_조회_성공을_검증한다(페이징된_서포터가_리뷰중인_러너_게시글_응답); + } + + @Test + void 로그인된_서포터의_완료된_러너_게시글_목록_조회에_성공한다() { + final RunnerPostResponse.ReferencedBySupporter 서포터가_리뷰_완료한_러너_게시글_응답 + = RunnerPostResponse.ReferencedBySupporter.of(완료된_게시글, 1); + final PageResponse 페이징된_서포터가_리뷰_완료한_러너_게시글_응답 + = 서포터가_리뷰_완료한_러너_게시글_응답(페이징_정보, List.of(서포터가_리뷰_완료한_러너_게시글_응답)); + + RunnerPostAssuredSupport + .클라이언트_요청() + .토큰으로_로그인한다(로그인용_토큰) + .로그인한_서포터의_러너_게시글_페이징을_조회한다(ReviewStatus.DONE, 페이징_정보) + + .서버_응답() + .서포터와_연관된_러너_게시글_페이징_조회_성공을_검증한다(페이징된_서포터가_리뷰_완료한_러너_게시글_응답); + } +} diff --git a/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadWithGuestAssuredTest.java b/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadWithSupporterIdAndReviewStatusAssuredTest.java similarity index 97% rename from backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadWithGuestAssuredTest.java rename to backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadWithSupporterIdAndReviewStatusAssuredTest.java index 72ddba6f5..8381cd24d 100644 --- a/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadWithGuestAssuredTest.java +++ b/backend/baton/src/test/java/touch/baton/assure/runnerpost/RunnerPostReadWithSupporterIdAndReviewStatusAssuredTest.java @@ -28,7 +28,8 @@ import static touch.baton.fixture.vo.MessageFixture.message; import static touch.baton.fixture.vo.ReviewCountFixture.reviewCount; -class RunnerPostReadWithGuestAssuredTest extends AssuredTestConfig { +@SuppressWarnings("NonAsciiCharacters") +class RunnerPostReadWithSupporterIdAndReviewStatusAssuredTest extends AssuredTestConfig { @Test void 서포터가_리뷰_완료한_러너_게시글_페이징_조회에_성공한다() { diff --git a/backend/baton/src/test/java/touch/baton/assure/supporter/SupporterProfileAssuredSupport.java b/backend/baton/src/test/java/touch/baton/assure/supporter/SupporterAssuredSupport.java similarity index 98% rename from backend/baton/src/test/java/touch/baton/assure/supporter/SupporterProfileAssuredSupport.java rename to backend/baton/src/test/java/touch/baton/assure/supporter/SupporterAssuredSupport.java index cdcc081ed..76930af2b 100644 --- a/backend/baton/src/test/java/touch/baton/assure/supporter/SupporterProfileAssuredSupport.java +++ b/backend/baton/src/test/java/touch/baton/assure/supporter/SupporterAssuredSupport.java @@ -13,9 +13,9 @@ import static org.assertj.core.api.SoftAssertions.assertSoftly; @SuppressWarnings("NonAsciiCharacters") -public class SupporterProfileAssuredSupport { +public class SupporterAssuredSupport { - private SupporterProfileAssuredSupport() { + private SupporterAssuredSupport() { } public static SupporterClientRequestBuilder 클라이언트_요청() { diff --git a/backend/baton/src/test/java/touch/baton/assure/supporter/SupporterProfileAssuredReadTest.java b/backend/baton/src/test/java/touch/baton/assure/supporter/SupporterReadBySupporterIdAssuredTest.java similarity index 92% rename from backend/baton/src/test/java/touch/baton/assure/supporter/SupporterProfileAssuredReadTest.java rename to backend/baton/src/test/java/touch/baton/assure/supporter/SupporterReadBySupporterIdAssuredTest.java index 983adc4ee..7b33fda8c 100644 --- a/backend/baton/src/test/java/touch/baton/assure/supporter/SupporterProfileAssuredReadTest.java +++ b/backend/baton/src/test/java/touch/baton/assure/supporter/SupporterReadBySupporterIdAssuredTest.java @@ -12,17 +12,17 @@ import java.util.List; -import static touch.baton.assure.supporter.SupporterProfileAssuredSupport.서포터_프로필_응답; +import static touch.baton.assure.supporter.SupporterAssuredSupport.서포터_프로필_응답; @SuppressWarnings("NonAsciiCharacters") -class SupporterProfileAssuredReadTest extends AssuredTestConfig { +class SupporterReadBySupporterIdAssuredTest extends AssuredTestConfig { @Test void 서포터_프로필을_조회한다() { final Member 사용자_헤나 = memberRepository.save(MemberFixture.createHyena()); final Supporter 서포터_헤나 = supporterRepository.save(SupporterFixture.create(사용자_헤나)); - SupporterProfileAssuredSupport + SupporterAssuredSupport .클라이언트_요청() .서포터_프로필을_서포터_식별자값으로_조회한다(서포터_헤나.getId()) @@ -43,7 +43,7 @@ class SupporterProfileAssuredReadTest extends AssuredTestConfig { final String 서포터_디투_토큰 = login(디투_소셜_아이디); // when, then - SupporterProfileAssuredSupport + SupporterAssuredSupport .클라이언트_요청() .로그인_한다(서포터_디투_토큰) .서포터_마이페이지를_토큰으로_조회한다() diff --git a/backend/baton/src/test/java/touch/baton/assure/supporter/SupporterProfileAssuredUpdateTest.java b/backend/baton/src/test/java/touch/baton/assure/supporter/SupporterUpdateAssuredTest.java similarity index 63% rename from backend/baton/src/test/java/touch/baton/assure/supporter/SupporterProfileAssuredUpdateTest.java rename to backend/baton/src/test/java/touch/baton/assure/supporter/SupporterUpdateAssuredTest.java index c4a183395..d0adade30 100644 --- a/backend/baton/src/test/java/touch/baton/assure/supporter/SupporterProfileAssuredUpdateTest.java +++ b/backend/baton/src/test/java/touch/baton/assure/supporter/SupporterUpdateAssuredTest.java @@ -15,7 +15,7 @@ import static touch.baton.domain.common.exception.ClientErrorCode.*; @SuppressWarnings("NonAsciiCharacters") -public class SupporterProfileAssuredUpdateTest extends AssuredTestConfig { +public class SupporterUpdateAssuredTest extends AssuredTestConfig { private String 디투_액세스_토큰; @@ -29,12 +29,12 @@ void setUp() { @Test void 서포터_정보를_수정한다() { - final SupporterUpdateRequest supporterUpdateRequest = new SupporterUpdateRequest("디투랜드", "우아한테크코스", "안녕하세요.", List.of("java", "spring")); + final SupporterUpdateRequest 서포터_수정_요청_값 = new SupporterUpdateRequest("디투랜드", "우아한테크코스", "안녕하세요.", List.of("java", "spring")); - SupporterProfileAssuredSupport + SupporterAssuredSupport .클라이언트_요청() .로그인_한다(디투_액세스_토큰) - .서포터_본인_프로필을_수정한다(supporterUpdateRequest) + .서포터_본인_프로필을_수정한다(서포터_수정_요청_값) .서버_응답() .서포터_본인_프로필_수정_성공을_검증한다(NO_CONTENT); @@ -42,12 +42,12 @@ void setUp() { @Test void 서포터_정보_수정_시에_이름이_없으면_예외가_발생한다() { - final SupporterUpdateRequest supporterUpdateRequest = new SupporterUpdateRequest(null, "우아한테크코스", "안녕하세요.", List.of("java", "spring")); + final SupporterUpdateRequest 서포터_수정_요청_값 = new SupporterUpdateRequest(null, "우아한테크코스", "안녕하세요.", List.of("java", "spring")); - SupporterProfileAssuredSupport + SupporterAssuredSupport .클라이언트_요청() .로그인_한다(디투_액세스_토큰) - .서포터_본인_프로필을_수정한다(supporterUpdateRequest) + .서포터_본인_프로필을_수정한다(서포터_수정_요청_값) .서버_응답() .서포터_본인_프로필_수정_실패를_검증한다(NAME_IS_NULL); @@ -55,12 +55,12 @@ void setUp() { @Test void 서포터_정보_수정_시에_소속이_없으면_예외가_발생한다() { - final SupporterUpdateRequest supporterUpdateRequest = new SupporterUpdateRequest("디투랜드", null, "안녕하세요.", List.of("java", "spring")); + final SupporterUpdateRequest 서포터_수정_요청_값 = new SupporterUpdateRequest("디투랜드", null, "안녕하세요.", List.of("java", "spring")); - SupporterProfileAssuredSupport + SupporterAssuredSupport .클라이언트_요청() .로그인_한다(디투_액세스_토큰) - .서포터_본인_프로필을_수정한다(supporterUpdateRequest) + .서포터_본인_프로필을_수정한다(서포터_수정_요청_값) .서버_응답() .서포터_본인_프로필_수정_실패를_검증한다(COMPANY_IS_NULL); @@ -68,12 +68,12 @@ void setUp() { @Test void 서포터_정보_수정_시에_소개글이_없어도_된다() { - final SupporterUpdateRequest supporterUpdateRequest = new SupporterUpdateRequest("디투랜드", "배달의민족", null, List.of("java", "spring")); + final SupporterUpdateRequest 서포터_수정_요청_값 = new SupporterUpdateRequest("디투랜드", "배달의민족", null, List.of("java", "spring")); - SupporterProfileAssuredSupport + SupporterAssuredSupport .클라이언트_요청() .로그인_한다(디투_액세스_토큰) - .서포터_본인_프로필을_수정한다(supporterUpdateRequest) + .서포터_본인_프로필을_수정한다(서포터_수정_요청_값) .서버_응답() .서포터_본인_프로필_수정_성공을_검증한다(NO_CONTENT); @@ -81,12 +81,12 @@ void setUp() { @Test void 서포터_정보_수정_시에_기술_태그가_없으면_예외가_발생한다() { - final SupporterUpdateRequest supporterUpdateRequest = new SupporterUpdateRequest("디투랜드", "배달의민족", "배달왕이 될거에요.", null); + final SupporterUpdateRequest 서포터_수정_요청_값 = new SupporterUpdateRequest("디투랜드", "배달의민족", "배달왕이 될거에요.", null); - SupporterProfileAssuredSupport + SupporterAssuredSupport .클라이언트_요청() .로그인_한다(디투_액세스_토큰) - .서포터_본인_프로필을_수정한다(supporterUpdateRequest) + .서포터_본인_프로필을_수정한다(서포터_수정_요청_값) .서버_응답() .서포터_본인_프로필_수정_실패를_검증한다(SUPPORTER_TECHNICAL_TAGS_ARE_NULL); diff --git a/backend/baton/src/test/java/touch/baton/controller/runner/RunnerAssuredSupport.java b/backend/baton/src/test/java/touch/baton/controller/runner/RunnerAssuredSupport.java deleted file mode 100644 index b65502b1b..000000000 --- a/backend/baton/src/test/java/touch/baton/controller/runner/RunnerAssuredSupport.java +++ /dev/null @@ -1,60 +0,0 @@ -package touch.baton.controller.runner; - -import io.restassured.response.ExtractableResponse; -import io.restassured.response.Response; -import touch.baton.assure.common.AssuredSupport; -import touch.baton.domain.runner.controller.response.RunnerMyProfileResponse; - -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -@SuppressWarnings("NonAsciiCharacters") -public class RunnerAssuredSupport { - - private RunnerAssuredSupport() { - } - - public static RunnerClientRequestBuilder 클라이언트_요청() { - return new RunnerClientRequestBuilder(); - } - - public static class RunnerClientRequestBuilder { - - private ExtractableResponse response; - - public RunnerClientRequestBuilder 러너_액세스_토큰으로_러너_프로필을_조회한다(final String 러너_액세스_토큰) { - response = AssuredSupport.get("/api/v1/profile/runner", 러너_액세스_토큰); - return this; - } - - public RunnerServerResponseBuilder 서버_응답() { - return new RunnerServerResponseBuilder(response); - } - } - - public static class RunnerServerResponseBuilder { - - private final ExtractableResponse response; - - public RunnerServerResponseBuilder(final ExtractableResponse response) { - this.response = response; - } - - public void 러너_본인_프로필_조회_성공을_검증한다(final RunnerMyProfileResponse 러너_프로필_응답) { - final RunnerMyProfileResponse actual = this.response.as(RunnerMyProfileResponse.class); - - assertSoftly(softly -> { - softly.assertThat(actual.profile().name()).isEqualTo(러너_프로필_응답.profile().name()); - softly.assertThat(actual.profile().imageUrl()).isEqualTo(러너_프로필_응답.profile().imageUrl()); - softly.assertThat(actual.profile().githubUrl()).isEqualTo(러너_프로필_응답.profile().githubUrl()); - softly.assertThat(actual.profile().introduction()).isEqualTo(러너_프로필_응답.profile().introduction()); - softly.assertThat(actual.runnerPosts().size()).isEqualTo(러너_프로필_응답.runnerPosts().size()); - softly.assertThat(actual.runnerPosts().get(0).runnerPostId()).isEqualTo(러너_프로필_응답.runnerPosts().get(0).runnerPostId()); - softly.assertThat(actual.runnerPosts().get(0).title()).isEqualTo(러너_프로필_응답.runnerPosts().get(0).title()); - softly.assertThat(actual.runnerPosts().get(0).deadline()).isEqualToIgnoringSeconds(러너_프로필_응답.runnerPosts().get(0).deadline()); - softly.assertThat(actual.runnerPosts().get(0).tags()).isEqualTo(러너_프로필_응답.runnerPosts().get(0).tags()); - softly.assertThat(actual.runnerPosts().get(0).reviewStatus()).isEqualTo(러너_프로필_응답.runnerPosts().get(0).reviewStatus()); - } - ); - } - } -} diff --git a/backend/baton/src/test/java/touch/baton/controller/runner/RunnerProfileAssuredReadTest.java b/backend/baton/src/test/java/touch/baton/controller/runner/RunnerProfileAssuredReadTest.java deleted file mode 100644 index 8ee34aa3e..000000000 --- a/backend/baton/src/test/java/touch/baton/controller/runner/RunnerProfileAssuredReadTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package touch.baton.controller.runner; - -import org.junit.jupiter.api.Test; -import touch.baton.config.AssuredTestConfig; - -@SuppressWarnings("NonAsciiCharacters") -public class RunnerProfileAssuredReadTest extends AssuredTestConfig { - - @Test - void 액세스_토큰으로_러너_본인의_정보_조회에_성공한다() { - // TODO: Access Token 으로 바꿔야함 -// final String accessToken = "abc123"; -// final Member memberHyena = memberRepository.save(MemberFixture.createHyena()); -// final Runner runnerHyena = runnerRepository.save(RunnerFixture.create(totalRating(0), Grade.BARE_FOOT, introduction("hello"), memberHyena)); -// final RunnerPost runnerPost = runnerPostRepository.save(RunnerPostFixture.create(runnerHyena, deadline(LocalDateTime.now().plusHours(100)))); -// -// RunnerAssuredSupport -// .클라이언트_요청().러너_액세스_토큰으로_러너_프로필을_조회한다(accessToken) -// .서버_응답().러너_본인_프로필_조회_성공을_검증한다(new RunnerMyProfileResponse( -// RunnerResponse.Mine.from(runnerHyena), -// List.of(RunnerPostResponse.Mine.from(runnerPost) -// ))); - } -} diff --git a/backend/baton/src/test/java/touch/baton/document/profile/member/read/MemberLoginProfileReadApiTest.java b/backend/baton/src/test/java/touch/baton/document/profile/member/read/MemberReadWithLoginedMemberApiTest.java similarity index 97% rename from backend/baton/src/test/java/touch/baton/document/profile/member/read/MemberLoginProfileReadApiTest.java rename to backend/baton/src/test/java/touch/baton/document/profile/member/read/MemberReadWithLoginedMemberApiTest.java index 3064f21ae..535a664db 100644 --- a/backend/baton/src/test/java/touch/baton/document/profile/member/read/MemberLoginProfileReadApiTest.java +++ b/backend/baton/src/test/java/touch/baton/document/profile/member/read/MemberReadWithLoginedMemberApiTest.java @@ -30,7 +30,7 @@ import static touch.baton.fixture.vo.SocialIdFixture.socialId; @WebMvcTest(MemberProfileController.class) -public class MemberLoginProfileReadApiTest extends RestdocsConfig { +public class MemberReadWithLoginedMemberApiTest extends RestdocsConfig { @BeforeEach void setUp() { diff --git a/backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerProfileReadApiTest.java b/backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerReadByGuestApiTest.java similarity index 89% rename from backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerProfileReadApiTest.java rename to backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerReadByGuestApiTest.java index 4a29acb80..a96404cea 100644 --- a/backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerProfileReadApiTest.java +++ b/backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerReadByGuestApiTest.java @@ -39,7 +39,7 @@ import static touch.baton.fixture.vo.TagNameFixture.tagName; @WebMvcTest(RunnerProfileController.class) -class RunnerProfileReadApiTest extends RestdocsConfig { +class RunnerReadByGuestApiTest extends RestdocsConfig { @MockBean private RunnerPostService runnerPostService; @@ -114,20 +114,4 @@ void readRunnerProfile() throws Exception { ) )); } - - // @DisplayName("러너 프로필 조회 API") -// @Test -// void read() throws Exception { -// // TODO: 로그인 들어오면 작성하겠삼. -// // given -// final Runner runner = RunnerFixture.createRunner(MemberFixture.createHyena()); -// final Deadline deadline = deadline(LocalDateTime.now().plusHours(100)); -// final Tag javaTag = TagFixture.create(tagName("자바"), tagCount(10)); -// final RunnerPost runnerPost = RunnerPostFixture.create(runner, deadline, List.of(javaTag)); -// final RunnerPost spyRunnerPost = spy(runnerPost); -// -// // when -// -// // then -// } } diff --git a/backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerReadByRunnerIdApiTest.java b/backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerReadByRunnerIdApiTest.java new file mode 100644 index 000000000..875d291fc --- /dev/null +++ b/backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerReadByRunnerIdApiTest.java @@ -0,0 +1,84 @@ +package touch.baton.document.profile.runner.read; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import touch.baton.config.RestdocsConfig; +import touch.baton.domain.member.Member; +import touch.baton.domain.runner.Runner; +import touch.baton.domain.runner.controller.RunnerProfileController; +import touch.baton.domain.runner.service.RunnerService; +import touch.baton.domain.runnerpost.service.RunnerPostService; +import touch.baton.domain.technicaltag.TechnicalTag; +import touch.baton.fixture.domain.MemberFixture; +import touch.baton.fixture.domain.RunnerFixture; +import touch.baton.fixture.domain.TechnicalTagFixture; + +import java.util.List; + +import static javax.swing.text.html.parser.DTDConstants.NUMBER; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.JsonFieldType.ARRAY; +import static org.springframework.restdocs.payload.JsonFieldType.STRING; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.pathParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(RunnerProfileController.class) +public class RunnerReadByRunnerIdApiTest extends RestdocsConfig { + + @MockBean + private RunnerPostService runnerPostService; + + @MockBean + private RunnerService runnerService; + + @BeforeEach + void setUp() { + final RunnerProfileController runnerProfileController = new RunnerProfileController(runnerPostService, runnerService); + restdocsSetUp(runnerProfileController); + } + + @DisplayName("러너 프로필 상세 조회 API") + @Test + void readRunnerProfile() throws Exception { + // given + final Member ethan = MemberFixture.createEthan(); + final TechnicalTag javaTag = TechnicalTagFixture.createJava(); + final TechnicalTag reactTag = TechnicalTagFixture.createReact(); + final Runner runner = RunnerFixture.createRunner(ethan, List.of(javaTag, reactTag)); + final Runner spyRunner = spy(runner); + + // when + when(spyRunner.getId()).thenReturn(1L); + when(runnerService.readByRunnerId(anyLong())).thenReturn(spyRunner); + + // then + mockMvc.perform(get("/api/v1/profile/runner/{runnerId}", 1L)) + .andExpect(status().isOk()) + .andExpect(content().contentType(APPLICATION_JSON)) + .andDo(restDocs.document( + pathParameters( + parameterWithName("runnerId").description("러너 식별자값") + ), + responseFields( + fieldWithPath("runnerId").type(NUMBER).description("러너 식별자값"), + fieldWithPath("name").type(STRING).description("러너 이름"), + fieldWithPath("imageUrl").type(STRING).description("사용자 이미지"), + fieldWithPath("githubUrl").type(STRING).description("깃허브 프로필 url"), + fieldWithPath("introduction").type(STRING).description("소개"), + fieldWithPath("company").type(STRING).description("소속"), + fieldWithPath("technicalTags").type(ARRAY).description("기술 스택") + ) + )); + } +} diff --git a/backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerReadWithLoginedRunnerApiTest.java b/backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerReadWithLoginedRunnerApiTest.java new file mode 100644 index 000000000..d8e9531a1 --- /dev/null +++ b/backend/baton/src/test/java/touch/baton/document/profile/runner/read/RunnerReadWithLoginedRunnerApiTest.java @@ -0,0 +1,80 @@ + +package touch.baton.document.profile.runner.read; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import touch.baton.config.RestdocsConfig; +import touch.baton.domain.runner.Runner; +import touch.baton.domain.runner.controller.RunnerProfileController; +import touch.baton.domain.runner.service.RunnerService; +import touch.baton.domain.runnerpost.service.RunnerPostService; +import touch.baton.domain.technicaltag.TechnicalTag; +import touch.baton.fixture.domain.MemberFixture; +import touch.baton.fixture.domain.RunnerFixture; +import touch.baton.fixture.domain.TechnicalTagFixture; + +import java.util.List; +import java.util.Optional; + +import static org.mockito.ArgumentMatchers.notNull; +import static org.mockito.BDDMockito.when; +import static org.springframework.http.HttpHeaders.AUTHORIZATION; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.JsonFieldType.ARRAY; +import static org.springframework.restdocs.payload.JsonFieldType.STRING; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static touch.baton.fixture.vo.TagNameFixture.tagName; + +@WebMvcTest(RunnerProfileController.class) +class RunnerReadWithLoginedRunnerApiTest extends RestdocsConfig { + + @MockBean + private RunnerPostService runnerPostService; + + @MockBean + private RunnerService runnerService; + + @BeforeEach + void setUp() { + final RunnerProfileController runnerProfileController = new RunnerProfileController(runnerPostService, runnerService); + restdocsSetUp(runnerProfileController); + } + + @DisplayName("러너 본인 프로필 조회 API") + @Test + void readMyProfileByToken() throws Exception { + // given + final TechnicalTag java = TechnicalTagFixture.create(tagName("java")); + final TechnicalTag spring = TechnicalTagFixture.create(tagName("spring")); + final Runner runner = RunnerFixture.createRunner(MemberFixture.createHyena(), List.of(java, spring)); + final String token = getAccessTokenBySocialId(runner.getMember().getSocialId().getValue()); + + when(oauthRunnerRepository.joinByMemberSocialId(notNull())) + .thenReturn(Optional.ofNullable(runner)); + + // then + mockMvc.perform(get("/api/v1/profile/runner/me") + .header(AUTHORIZATION, "Bearer " + token)) + .andDo(print()) + .andDo(restDocs.document( + requestHeaders( + headerWithName(AUTHORIZATION).description("Bearer JWT") + ), + responseFields( + fieldWithPath("name").type(STRING).description("러너 이름"), + fieldWithPath("company").type(STRING).description("러너 소속 회사"), + fieldWithPath("imageUrl").type(STRING).description("러너 프로필 이미지 url"), + fieldWithPath("githubUrl").type(STRING).description("러너 깃허브 url"), + fieldWithPath("introduction").type(STRING).description("러너 자기소개"), + fieldWithPath("technicalTags").type(ARRAY).description("러너 기술 태그 목록") + ) + )); + } +} diff --git a/backend/baton/src/test/java/touch/baton/document/profile/runner/update/RunnerProfileUpdateApiTest.java b/backend/baton/src/test/java/touch/baton/document/profile/runner/update/RunnerUpdateApiTest.java similarity index 88% rename from backend/baton/src/test/java/touch/baton/document/profile/runner/update/RunnerProfileUpdateApiTest.java rename to backend/baton/src/test/java/touch/baton/document/profile/runner/update/RunnerUpdateApiTest.java index 7c8d61794..ae041ab27 100644 --- a/backend/baton/src/test/java/touch/baton/document/profile/runner/update/RunnerProfileUpdateApiTest.java +++ b/backend/baton/src/test/java/touch/baton/document/profile/runner/update/RunnerUpdateApiTest.java @@ -13,7 +13,6 @@ import touch.baton.domain.runner.service.RunnerService; import touch.baton.domain.runner.service.dto.RunnerUpdateRequest; import touch.baton.domain.runnerpost.service.RunnerPostService; -import touch.baton.domain.supporter.controller.SupporterProfileController; import touch.baton.fixture.domain.MemberFixture; import touch.baton.fixture.domain.RunnerFixture; @@ -22,12 +21,8 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -import static org.springframework.http.HttpHeaders.AUTHORIZATION; -import static org.springframework.http.HttpHeaders.CONTENT_TYPE; -import static org.springframework.http.HttpHeaders.LOCATION; -import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; -import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; -import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; +import static org.springframework.http.HttpHeaders.*; +import static org.springframework.restdocs.headers.HeaderDocumentation.*; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; import static org.springframework.restdocs.payload.JsonFieldType.ARRAY; import static org.springframework.restdocs.payload.JsonFieldType.STRING; @@ -38,7 +33,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(RunnerProfileController.class) -public class RunnerProfileUpdateApiTest extends RestdocsConfig { +public class RunnerUpdateApiTest extends RestdocsConfig { @MockBean private RunnerService runnerService; diff --git a/backend/baton/src/test/java/touch/baton/document/profile/supporter/read/SupporterProfileReadApiTest.java b/backend/baton/src/test/java/touch/baton/document/profile/supporter/read/SupporterReadByGuestApiTest.java similarity index 96% rename from backend/baton/src/test/java/touch/baton/document/profile/supporter/read/SupporterProfileReadApiTest.java rename to backend/baton/src/test/java/touch/baton/document/profile/supporter/read/SupporterReadByGuestApiTest.java index 4305f6210..f1821e198 100644 --- a/backend/baton/src/test/java/touch/baton/document/profile/supporter/read/SupporterProfileReadApiTest.java +++ b/backend/baton/src/test/java/touch/baton/document/profile/supporter/read/SupporterReadByGuestApiTest.java @@ -26,9 +26,7 @@ import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; -import static org.springframework.restdocs.payload.JsonFieldType.ARRAY; -import static org.springframework.restdocs.payload.JsonFieldType.NUMBER; -import static org.springframework.restdocs.payload.JsonFieldType.STRING; +import static org.springframework.restdocs.payload.JsonFieldType.*; import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; @@ -39,7 +37,7 @@ import static touch.baton.fixture.vo.TagNameFixture.tagName; @WebMvcTest(SupporterProfileController.class) -class SupporterProfileReadApiTest extends RestdocsConfig { +class SupporterReadByGuestApiTest extends RestdocsConfig { @MockBean private SupporterService supporterService; diff --git a/backend/baton/src/test/java/touch/baton/document/profile/supporter/update/SupporterProfileUpdateApiTest.java b/backend/baton/src/test/java/touch/baton/document/profile/supporter/update/SupporterUpdateApiTest.java similarity index 98% rename from backend/baton/src/test/java/touch/baton/document/profile/supporter/update/SupporterProfileUpdateApiTest.java rename to backend/baton/src/test/java/touch/baton/document/profile/supporter/update/SupporterUpdateApiTest.java index 20bac97c7..f241889df 100644 --- a/backend/baton/src/test/java/touch/baton/document/profile/supporter/update/SupporterProfileUpdateApiTest.java +++ b/backend/baton/src/test/java/touch/baton/document/profile/supporter/update/SupporterUpdateApiTest.java @@ -38,7 +38,7 @@ import static touch.baton.fixture.vo.SocialIdFixture.socialId; @WebMvcTest(SupporterProfileController.class) -public class SupporterProfileUpdateApiTest extends RestdocsConfig { +public class SupporterUpdateApiTest extends RestdocsConfig { @MockBean private SupporterService supporterService; diff --git a/backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadApiTest.java b/backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadAllApiTest.java similarity index 99% rename from backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadApiTest.java rename to backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadAllApiTest.java index 7cb641853..360b9219a 100644 --- a/backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadApiTest.java +++ b/backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadAllApiTest.java @@ -56,7 +56,7 @@ import static touch.baton.fixture.vo.TagNameFixture.tagName; @WebMvcTest(RunnerPostController.class) -class RunnerPostReadApiTest extends RestdocsConfig { +class RunnerPostReadAllApiTest extends RestdocsConfig { @MockBean private RunnerPostService runnerPostService; diff --git a/backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadOfSupporterByGuestApiTest.java b/backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadOfSupporterByGuestApiTest.java new file mode 100644 index 000000000..904b99607 --- /dev/null +++ b/backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadOfSupporterByGuestApiTest.java @@ -0,0 +1,121 @@ +package touch.baton.document.runnerpost.read; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import touch.baton.config.RestdocsConfig; +import touch.baton.domain.runner.Runner; +import touch.baton.domain.runnerpost.RunnerPost; +import touch.baton.domain.runnerpost.controller.RunnerPostController; +import touch.baton.domain.runnerpost.service.RunnerPostService; +import touch.baton.domain.runnerpost.vo.Deadline; +import touch.baton.domain.runnerpost.vo.ReviewStatus; +import touch.baton.domain.supporter.Supporter; +import touch.baton.domain.tag.Tag; +import touch.baton.fixture.domain.MemberFixture; +import touch.baton.fixture.domain.RunnerFixture; +import touch.baton.fixture.domain.RunnerPostFixture; +import touch.baton.fixture.domain.SupporterFixture; +import touch.baton.fixture.domain.TagFixture; + +import java.time.LocalDateTime; +import java.util.List; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.JsonFieldType.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.queryParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static touch.baton.fixture.domain.TechnicalTagFixture.createJava; +import static touch.baton.fixture.domain.TechnicalTagFixture.createSpring; +import static touch.baton.fixture.vo.DeadlineFixture.deadline; +import static touch.baton.fixture.vo.ReviewCountFixture.reviewCount; +import static touch.baton.fixture.vo.TagNameFixture.tagName; + +@WebMvcTest(RunnerPostController.class) +public class RunnerPostReadOfSupporterByGuestApiTest extends RestdocsConfig { + + @MockBean + private RunnerPostService runnerPostService; + + @BeforeEach + void setUp() { + final RunnerPostController runnerPostController = new RunnerPostController(runnerPostService); + restdocsSetUp(runnerPostController); + } + + @DisplayName("서포터와 연관된 러너 게시글 페이징 조회 API") + @Test + void readReferencedBySupporter() throws Exception { + // given + final Runner runnerJudy = RunnerFixture.createRunner(MemberFixture.createJudy()); + final Supporter supporterHyena = SupporterFixture.create(reviewCount(10), MemberFixture.createHyena(), List.of(createJava(), createSpring())); + + final Tag javaTag = TagFixture.create(tagName("자바")); + final Deadline deadline = deadline(LocalDateTime.now().plusHours(100)); + final RunnerPost runnerPost = RunnerPostFixture.create(runnerJudy, deadline, List.of(javaTag)); + runnerPost.assignSupporter(supporterHyena); + + // when + final RunnerPost spyRunnerPost = spy(runnerPost); + final Supporter spySupporterHyena = spy(supporterHyena); + when(spySupporterHyena.getId()).thenReturn(1L); + when(spyRunnerPost.getId()).thenReturn(1L); + + final List runnerPosts = List.of(spyRunnerPost); + final PageRequest pageOne = PageRequest.of(1, 10); + final PageImpl pageRunnerPosts = new PageImpl<>(runnerPosts, pageOne, runnerPosts.size()); + when(runnerPostService.readRunnerPostsBySupporterIdAndReviewStatus(any(), any(), any())) + .thenReturn(pageRunnerPosts); + when(runnerPostService.readCountsByRunnerPostIds(anyList())) + .thenReturn(List.of(1L)); + + // then + mockMvc.perform(get("/api/v1/posts/runner/search") + .characterEncoding(UTF_8) + .accept(APPLICATION_JSON) + .queryParam("size", String.valueOf(pageOne.getPageSize())) + .queryParam("page", String.valueOf(pageOne.getPageNumber())) + .queryParam("supporterId", String.valueOf(spySupporterHyena.getId())) + .queryParam("reviewStatus", ReviewStatus.IN_PROGRESS.name())) + .andExpect(status().isOk()) + .andExpect(content().contentType(APPLICATION_JSON)) + .andDo(restDocs.document( + queryParameters( + parameterWithName("size").description("페이지 사이즈"), + parameterWithName("page").description("페이지 번호"), + parameterWithName("supporterId").description("서포터 식별자값"), + parameterWithName("reviewStatus").description("리뷰 상태") + ), + responseFields( + fieldWithPath("pageInfo.isFirst").type(BOOLEAN).description("첫 번째 페이지인지"), + fieldWithPath("pageInfo.isLast").type(BOOLEAN).description("마지막 페이지 인지"), + fieldWithPath("pageInfo.hasNext").type(BOOLEAN).description("다음 페이지가 있는지"), + fieldWithPath("pageInfo.totalPages").type(NUMBER).description("총 페이지 수"), + fieldWithPath("pageInfo.totalElements").type(NUMBER).description("총 데이터 수"), + fieldWithPath("pageInfo.currentPage").type(NUMBER).description("현재 페이지 번호"), + fieldWithPath("pageInfo.currentSize").type(NUMBER).description("현재 페이지 데이터 수"), + fieldWithPath("data.[].runnerPostId").type(NUMBER).description("러너 게시글 식별자값(id)"), + fieldWithPath("data.[].title").type(STRING).description("러너 게시글 제목"), + fieldWithPath("data.[].deadline").type(STRING).description("러너 게시글의 마감 기한"), + fieldWithPath("data.[].tags").type(ARRAY).description("러너 게시글 태그 목록"), + fieldWithPath("data.[].watchedCount").type(NUMBER).description("러너 게시글의 조회수"), + fieldWithPath("data.[].applicantCount").type(NUMBER).description("러너 게시글에 신청한 서포터 수"), + fieldWithPath("data.[].reviewStatus").type(STRING).description("러너 게시글 리뷰 상태") + )) + ); + } +} diff --git a/backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadWithLoginedSupporterApiTest.java b/backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadWithLoginedSupporterApiTest.java new file mode 100644 index 000000000..0662e2850 --- /dev/null +++ b/backend/baton/src/test/java/touch/baton/document/runnerpost/read/RunnerPostReadWithLoginedSupporterApiTest.java @@ -0,0 +1,139 @@ +package touch.baton.document.runnerpost.read; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import touch.baton.config.RestdocsConfig; +import touch.baton.domain.member.Member; +import touch.baton.domain.runner.Runner; +import touch.baton.domain.runnerpost.RunnerPost; +import touch.baton.domain.runnerpost.controller.RunnerPostController; +import touch.baton.domain.runnerpost.service.RunnerPostService; +import touch.baton.domain.runnerpost.vo.Deadline; +import touch.baton.domain.runnerpost.vo.ReviewStatus; +import touch.baton.domain.supporter.Supporter; +import touch.baton.domain.tag.Tag; +import touch.baton.fixture.domain.MemberFixture; +import touch.baton.fixture.domain.RunnerFixture; +import touch.baton.fixture.domain.RunnerPostFixture; +import touch.baton.fixture.domain.SupporterFixture; +import touch.baton.fixture.domain.TagFixture; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; +import static org.springframework.http.HttpHeaders.AUTHORIZATION; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.payload.JsonFieldType.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.queryParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static touch.baton.fixture.vo.CompanyFixture.company; +import static touch.baton.fixture.vo.DeadlineFixture.deadline; +import static touch.baton.fixture.vo.GithubUrlFixture.githubUrl; +import static touch.baton.fixture.vo.ImageUrlFixture.imageUrl; +import static touch.baton.fixture.vo.MemberNameFixture.memberName; +import static touch.baton.fixture.vo.OauthIdFixture.oauthId; +import static touch.baton.fixture.vo.SocialIdFixture.socialId; +import static touch.baton.fixture.vo.TagNameFixture.tagName; + +@WebMvcTest(RunnerPostController.class) +public class RunnerPostReadWithLoginedSupporterApiTest extends RestdocsConfig { + + @MockBean + private RunnerPostService runnerPostService; + + @BeforeEach + void setUp() { + final RunnerPostController runnerPostController = new RunnerPostController(runnerPostService); + restdocsSetUp(runnerPostController); + } + + @DisplayName("로그인한 서포터가 참여한 러너 게시글 페이징 조회 API") + @Test + void readRunnerPostsByLoginedSupporterAndReviewStatus() throws Exception { + // given + final Runner runnerJudy = RunnerFixture.createRunner(MemberFixture.createJudy()); + final String socialId = "ditooSocialId"; + final Member loginedMember = MemberFixture.create( + memberName("디투"), + socialId(socialId), + oauthId("abcd"), + githubUrl("naver.com"), + company("우아한테크코스"), + imageUrl("profile.jpg") + ); + final Supporter loginedSupporter = SupporterFixture.create(loginedMember); + final String token = getAccessTokenBySocialId(socialId); + + final Tag javaTag = TagFixture.create(tagName("자바")); + final Deadline deadline = deadline(LocalDateTime.now().plusHours(100)); + final RunnerPost runnerPost = RunnerPostFixture.create(runnerJudy, deadline, List.of(javaTag)); + runnerPost.assignSupporter(loginedSupporter); + + // when + final RunnerPost spyRunnerPost = spy(runnerPost); + final Supporter spyLoginedSupporter = spy(loginedSupporter); + when(oauthSupporterRepository.joinByMemberSocialId(any())) + .thenReturn(Optional.ofNullable(spyLoginedSupporter)); + when(spyRunnerPost.getId()).thenReturn(1L); + + final List runnerPosts = List.of(spyRunnerPost); + final PageRequest pageOne = PageRequest.of(1, 10); + final PageImpl pageRunnerPosts = new PageImpl<>(runnerPosts, pageOne, runnerPosts.size()); + when(runnerPostService.readRunnerPostsBySupporterIdAndReviewStatus(any(), any(), any())) + .thenReturn(pageRunnerPosts); + when(runnerPostService.readCountsByRunnerPostIds(anyList())) + .thenReturn(List.of(1L)); + + // then + mockMvc.perform(get("/api/v1/posts/runner/me/supporter") + .header(AUTHORIZATION, "Bearer " + token) + .queryParam("size", String.valueOf(pageOne.getPageSize())) + .queryParam("page", String.valueOf(pageOne.getPageNumber())) + .queryParam("reviewStatus", ReviewStatus.IN_PROGRESS.name())) + .andExpect(status().isOk()) + .andExpect(content().contentType(APPLICATION_JSON)) + .andDo(restDocs.document( + requestHeaders( + headerWithName(AUTHORIZATION).description("Bearer JWT") + ), + queryParameters( + parameterWithName("size").description("페이지 사이즈"), + parameterWithName("page").description("페이지 번호"), + parameterWithName("reviewStatus").description("리뷰 상태") + ), + responseFields( + fieldWithPath("pageInfo.isFirst").type(BOOLEAN).description("첫 번째 페이지인지"), + fieldWithPath("pageInfo.isLast").type(BOOLEAN).description("마지막 페이지 인지"), + fieldWithPath("pageInfo.hasNext").type(BOOLEAN).description("다음 페이지가 있는지"), + fieldWithPath("pageInfo.totalPages").type(NUMBER).description("총 페이지 수"), + fieldWithPath("pageInfo.totalElements").type(NUMBER).description("총 데이터 수"), + fieldWithPath("pageInfo.currentPage").type(NUMBER).description("현재 페이지 번호"), + fieldWithPath("pageInfo.currentSize").type(NUMBER).description("현재 페이지 데이터 수"), + fieldWithPath("data.[].runnerPostId").type(NUMBER).description("러너 게시글 식별자값(id)"), + fieldWithPath("data.[].title").type(STRING).description("러너 게시글 제목"), + fieldWithPath("data.[].deadline").type(STRING).description("러너 게시글의 마감 기한"), + fieldWithPath("data.[].tags").type(ARRAY).description("러너 게시글 태그 목록"), + fieldWithPath("data.[].watchedCount").type(NUMBER).description("러너 게시글의 조회수"), + fieldWithPath("data.[].applicantCount").type(NUMBER).description("러너 게시글에 신청한 서포터 수"), + fieldWithPath("data.[].reviewStatus").type(STRING).description("러너 게시글 리뷰 상태") + )) + ); + } +} diff --git a/backend/baton/src/test/java/touch/baton/domain/runnerpost/repository/RunnerPostRepositoryTest.java b/backend/baton/src/test/java/touch/baton/domain/runnerpost/repository/RunnerPostRepositoryTest.java index 08e913ce1..82bf09e96 100644 --- a/backend/baton/src/test/java/touch/baton/domain/runnerpost/repository/RunnerPostRepositoryTest.java +++ b/backend/baton/src/test/java/touch/baton/domain/runnerpost/repository/RunnerPostRepositoryTest.java @@ -84,6 +84,47 @@ void findBySupporterIdAndReviewStatus() { final Page pageTwoRunnerPosts = runnerPostRepository.findBySupporterIdAndReviewStatus(pageTwo, savedSupporterHyena.getId(), ReviewStatus.DONE); + // then + assertSoftly(softly -> { + softly.assertThat(pageOneRunnerPosts.getContent()).containsExactly(savedRunnerPostOne, savedRunnerPostTwo); + softly.assertThat(pageTwoRunnerPosts.getContent()).containsExactly(savedRunnerPostThree); + }); + } + + @DisplayName("join 한 SupporterRunnerPost의 Supporter 외래키가 Supporter 식별자값과 같고, ReviewStatus 로 연관된 RunnerPost 를 페이징하여 조회한다.") + @Test + void joinSupporterRunnerPostBySupporterIdAndReviewStatus() { + // given + final Member savedMemberDitoo = memberRepository.save(MemberFixture.createDitoo()); + final Runner savedRunnerDitoo = runnerRepository.save(RunnerFixture.createRunner(savedMemberDitoo)); + final Member savedMemberEthan = memberRepository.save(MemberFixture.createEthan()); + final Runner savedRunnerEthan = runnerRepository.save(RunnerFixture.createRunner(savedMemberEthan)); + final Member savedMemberJudy = memberRepository.save(MemberFixture.createJudy()); + final Runner savedRunnerJudy = runnerRepository.save(RunnerFixture.createRunner(savedMemberJudy)); + + final Member savedMemberHyena = memberRepository.save(MemberFixture.createHyena()); + final Supporter savedApplicantHyena = supporterRepository.save(SupporterFixture.create(savedMemberHyena)); + + final RunnerPost runnerPostOne = RunnerPostFixture.create(savedRunnerDitoo, new Deadline(LocalDateTime.now().plusHours(100))); + final RunnerPost savedRunnerPostOne = runnerPostRepository.save(runnerPostOne); + supporterRunnerPostRepository.save(SupporterRunnerPostFixture.create(savedRunnerPostOne, savedApplicantHyena)); + final RunnerPost runnerPostTwo = RunnerPostFixture.create(savedRunnerEthan, new Deadline(LocalDateTime.now().plusHours(100))); + final RunnerPost savedRunnerPostTwo = runnerPostRepository.save(runnerPostTwo); + supporterRunnerPostRepository.save(SupporterRunnerPostFixture.create(savedRunnerPostTwo, savedApplicantHyena)); + final RunnerPost runnerPostThree = RunnerPostFixture.create(savedRunnerJudy, new Deadline(LocalDateTime.now().plusHours(100))); + final RunnerPost savedRunnerPostThree = runnerPostRepository.save(runnerPostThree); + supporterRunnerPostRepository.save(SupporterRunnerPostFixture.create(savedRunnerPostThree, savedApplicantHyena)); + + // when + final PageRequest pageOne = PageRequest.of(0, 2); + final PageRequest pageTwo = PageRequest.of(1, 2); + + final Page pageOneRunnerPosts + = runnerPostRepository.joinSupporterRunnerPostBySupporterIdAndReviewStatus(pageOne, savedApplicantHyena.getId(), ReviewStatus.NOT_STARTED); + final Page pageTwoRunnerPosts + = runnerPostRepository.joinSupporterRunnerPostBySupporterIdAndReviewStatus(pageTwo, savedApplicantHyena.getId(), ReviewStatus.NOT_STARTED); + + // then assertSoftly(softly -> { softly.assertThat(pageOneRunnerPosts.getContent()).containsExactly(savedRunnerPostOne, savedRunnerPostTwo); softly.assertThat(pageTwoRunnerPosts.getContent()).containsExactly(savedRunnerPostThree); diff --git a/backend/baton/src/test/java/touch/baton/domain/runnerpost/repository/read/RunnerPostRepositoryReadTest.java b/backend/baton/src/test/java/touch/baton/domain/runnerpost/repository/read/RunnerPostRepositoryReadTest.java index 7934ba08f..60e38f461 100644 --- a/backend/baton/src/test/java/touch/baton/domain/runnerpost/repository/read/RunnerPostRepositoryReadTest.java +++ b/backend/baton/src/test/java/touch/baton/domain/runnerpost/repository/read/RunnerPostRepositoryReadTest.java @@ -1,19 +1,17 @@ package touch.baton.domain.runnerpost.repository.read; +import jakarta.persistence.EntityManager; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import touch.baton.config.RepositoryTestConfig; import touch.baton.domain.member.Member; -import touch.baton.domain.member.repository.MemberRepository; import touch.baton.domain.runner.Runner; -import touch.baton.domain.runner.repository.RunnerRepository; import touch.baton.domain.runnerpost.RunnerPost; import touch.baton.domain.runnerpost.repository.RunnerPostRepository; import touch.baton.domain.tag.RunnerPostTag; import touch.baton.domain.tag.Tag; import touch.baton.domain.tag.repository.RunnerPostTagRepository; -import touch.baton.domain.tag.repository.TagRepository; import touch.baton.fixture.domain.MemberFixture; import touch.baton.fixture.domain.RunnerFixture; import touch.baton.fixture.domain.RunnerPostFixture; @@ -36,29 +34,23 @@ class RunnerPostRepositoryReadTest extends RepositoryTestConfig { - @Autowired - private MemberRepository memberRepository; - - @Autowired - private RunnerRepository runnerRepository; - @Autowired private RunnerPostRepository runnerPostRepository; @Autowired - private TagRepository tagRepository; + private RunnerPostTagRepository runnerPostTagRepository; @Autowired - private RunnerPostTagRepository runnerPostTagRepository; + private EntityManager entityManager; @DisplayName("RunnerPost 식별자로 RunnerPostTag 목록을 조회할 때 Tag 가 있으면 조회된다.") @Test void findRunnerPostTagsById_exist() { // given final Member ditoo = MemberFixture.createDitoo(); - memberRepository.save(ditoo); + entityManager.persist(ditoo); final Runner runner = RunnerFixture.createRunner(ditoo); - runnerRepository.save(runner); + entityManager.persist(runner); final RunnerPost runnerPost = RunnerPostFixture.create(title("제 코드를 리뷰해주세요"), contents("제 코드의 내용은 이렇습니다."), @@ -72,9 +64,9 @@ void findRunnerPostTagsById_exist() { runnerPostRepository.save(runnerPost); final Tag java = TagFixture.createJava(); - tagRepository.save(java); + entityManager.persist(java); final Tag spring = TagFixture.createSpring(); - tagRepository.save(spring); + entityManager.persist(spring); final RunnerPostTag javaRunnerPostTag = RunnerPostTagFixture.create(runnerPost, java); final RunnerPostTag springRunnerPostTag = RunnerPostTagFixture.create(runnerPost, spring); @@ -92,9 +84,9 @@ void findRunnerPostTagsById_exist() { void findByRunnerId() { // given final Member ditoo = MemberFixture.createDitoo(); - memberRepository.save(ditoo); + entityManager.persist(ditoo); final Runner runner = RunnerFixture.createRunner(ditoo); - runnerRepository.save(runner); + entityManager.persist(runner); final RunnerPost runnerPost = RunnerPostFixture.create(title("제 코드를 리뷰해주세요"), contents("제 코드의 내용은 이렇습니다."), @@ -119,9 +111,9 @@ void findByRunnerId() { void findAllByOrderByCreatedAt() { // given final Member ditoo = MemberFixture.createDitoo(); - memberRepository.save(ditoo); + entityManager.persist(ditoo); final Runner runner = RunnerFixture.createRunner(ditoo); - runnerRepository.save(runner); + entityManager.persist(runner); final RunnerPost previousRunnerPost = RunnerPostFixture.create(title("제 코드를 리뷰해주세요"), contents("제 코드의 내용은 이렇습니다."), diff --git a/backend/baton/src/test/java/touch/baton/domain/runnerpost/service/RunnerPostServiceReadTest.java b/backend/baton/src/test/java/touch/baton/domain/runnerpost/service/RunnerPostServiceReadTest.java index 95ce6beb6..dec7c9d24 100644 --- a/backend/baton/src/test/java/touch/baton/domain/runnerpost/service/RunnerPostServiceReadTest.java +++ b/backend/baton/src/test/java/touch/baton/domain/runnerpost/service/RunnerPostServiceReadTest.java @@ -43,6 +43,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.SoftAssertions.assertSoftly; import static org.junit.jupiter.api.Assertions.assertAll; +import static touch.baton.domain.runnerpost.vo.ReviewStatus.NOT_STARTED; import static touch.baton.fixture.vo.DeadlineFixture.deadline; class RunnerPostServiceReadTest extends ServiceTestConfig { @@ -88,7 +89,7 @@ void success_findByRunnerPostId() { .pullRequestUrl(new PullRequestUrl("https://")) .watchedCount(new WatchedCount(0)) .runnerPostTags(new RunnerPostTags(new ArrayList<>())) - .reviewStatus(ReviewStatus.NOT_STARTED) + .reviewStatus(NOT_STARTED) .runner(runner) .supporter(null) .build(); @@ -144,9 +145,9 @@ void success_findByRunnerId() { }); } - @DisplayName("Supporter 외래키와 ReviewStatus 로 러너 게시글을 조회한다.") + @DisplayName("Supporter 외래키와 ReviewStatus 가 NOT_STARTED 가 아닌 것으로 러너 게시글을 조회한다.") @Test - void readRunnerPostsBySupporterIdAndReviewStatus() { + void readRunnerPostsBySupporterIdAndReviewStatusIsNot_NOT_STARTED() { // given final Member savedMemberEthan = memberRepository.save(MemberFixture.createEthan()); final Runner savedRunnerEthan = runnerRepository.save(RunnerFixture.createRunner(savedMemberEthan)); @@ -210,4 +211,31 @@ void readCountByRunnerPostId_is_null_then_return_zero() { // then1 assertThat(foundApplicantCount).isZero(); } + + @DisplayName("Supporter 외래키와 ReviewStatus 가 NOT_STARTED 로 러너 게시글을 조회한다.") + @Test + void readRunnerPostsBySupporterIdAndReviewStatusIs_NOT_STARTED() { + // given + final Member savedMemberEthan = memberRepository.save(MemberFixture.createEthan()); + final Runner savedRunnerEthan = runnerRepository.save(RunnerFixture.createRunner(savedMemberEthan)); + + final Member savedMemberHyena = memberRepository.save(MemberFixture.createHyena()); + final Supporter savedSupporterHyena = supporterRepository.save(SupporterFixture.create(savedMemberHyena)); + + final RunnerPost runnerPost = RunnerPostFixture.create(savedRunnerEthan, deadline(now().plusHours(100))); + final RunnerPost savedRunnerPost = runnerPostRepository.save(runnerPost); + + supporterRunnerPostRepository.save(SupporterRunnerPostFixture.create(runnerPost, savedSupporterHyena)); + + // when + final PageRequest pageable = PageRequest.of(0, 10); + final Page pageRunnerPosts + = runnerPostService.readRunnerPostsBySupporterIdAndReviewStatus(pageable, savedSupporterHyena.getId(), NOT_STARTED); + + // then + assertAll( + () -> assertThat(pageRunnerPosts.getPageable()).isEqualTo(pageable), + () -> assertThat(pageRunnerPosts.getContent()).containsExactly(savedRunnerPost) + ); + } } diff --git a/backend/baton/src/test/java/touch/baton/fixture/domain/RunnerPostFixture.java b/backend/baton/src/test/java/touch/baton/fixture/domain/RunnerPostFixture.java index fd5338a01..6b17699e5 100644 --- a/backend/baton/src/test/java/touch/baton/fixture/domain/RunnerPostFixture.java +++ b/backend/baton/src/test/java/touch/baton/fixture/domain/RunnerPostFixture.java @@ -152,7 +152,11 @@ public static RunnerPost create(final Runner runner, final Supporter supporter, .build(); } - public static RunnerPost create(final Runner runner, final Supporter supporter, final Deadline deadline, final ReviewStatus reviewStatus) { + public static RunnerPost create(final Runner runner, + final Supporter supporter, + final Deadline deadline, + final ReviewStatus reviewStatus + ) { return RunnerPost.builder() .title(new Title("테스트 제목")) .contents(new Contents("테스트 내용"))