Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

러너 및 서포터의 게시글 개수 조회 api 구현 #646

Merged
merged 19 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
60cc8cc
feat: 러너 식별자 값으로 러너 게시글 카운트 쿼리 작성
shb03323 Oct 10, 2023
cfd34d9
refactor: secret 업데이트
shb03323 Oct 10, 2023
4636bf1
feat: Supporter 와 관련된 게시글 수 조회 repository 구현
shb03323 Oct 10, 2023
92584eb
feat: RunnerId 와 ReviewStatus 로 러너 게시글 조회 service 구현
shb03323 Oct 10, 2023
4d07ca7
feat: RunnerId 와 reviewStatus 로 로그인 된 러너의 게시글 개수 조회 api 구현
shb03323 Oct 10, 2023
2e78e44
Merge branch 'dev/BE' into feat/626
shb03323 Oct 10, 2023
965c203
test: 로그인한 러너와 관련된 러너 게시글 개수 조회 인수 테스트
shb03323 Oct 10, 2023
b48ba39
test: 러너와 연관된 러너 게시글 개수 조회 rest docs 테스트
shb03323 Oct 10, 2023
77568e7
refactor: SupporterRunnerPostRepository 관련 코드 정리
shb03323 Oct 10, 2023
071e903
test: supporter 테스트 파일 구조 변경
shb03323 Oct 10, 2023
c0cbf4f
feat: 서포터 식별자 값으로 러너 게시글 개수 조회 서비스 로직 구현
shb03323 Oct 10, 2023
e0231fa
feat: 서포터 식별자 값으로 러너 게시글 개수 조회 api 구현
shb03323 Oct 10, 2023
1849b94
test: 서포터 관련 러너 게시글 개수 조회 인수 테스트
shb03323 Oct 10, 2023
f2c5882
test: 로그인한 서포터 관련 러너 게시글 개수 조회 api 테스트
shb03323 Oct 10, 2023
3b4aa0d
test: 잘못된 테스트 수정
shb03323 Oct 10, 2023
0db6274
test: 서포터가 리뷰 완료한 러너 게시글 개수 조회 api 테스트
shb03323 Oct 10, 2023
9ccfe3a
Merge branch 'dev/BE' into feat/626
shb03323 Oct 10, 2023
9cc226f
refactor: 서브 모듈 업데이트
shb03323 Oct 10, 2023
150a0b7
refactor: reference 타입을 primitive 타입으로 변경
shb03323 Oct 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 63 additions & 1 deletion backend/baton/src/docs/asciidoc/RunnerPostReadApi.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,28 @@ include::{snippets}/../../build/generated-snippets/runner-post-read-with-logined

include::{snippets}/../../build/generated-snippets/runner-post-read-with-logined-runner-api-test/read-runner-post-by-logined-runner-and-review-status/response-fields.adoc[]

==== *러너 마이페이지 게시글 개수 조회 API*

===== *Http Request*

include::{snippets}/../../build/generated-snippets/runner-post-count-with-logined-runner-api-test/count-runner-post-by-logined-runner-and-review-status/http-request.adoc[]

===== *Http Request Headers*

include::{snippets}/../../build/generated-snippets/runner-post-count-with-logined-runner-api-test/count-runner-post-by-logined-runner-and-review-status/request-headers.adoc[]

===== *Http Request Query Parameters*

include::{snippets}/../../build/generated-snippets/runner-post-count-with-logined-runner-api-test/count-runner-post-by-logined-runner-and-review-status/query-parameters.adoc[]

===== *Http Response*

include::{snippets}/../../build/generated-snippets/runner-post-count-with-logined-runner-api-test/count-runner-post-by-logined-runner-and-review-status/http-response.adoc[]

===== *Http Response Fields*

include::{snippets}/../../build/generated-snippets/runner-post-count-with-logined-runner-api-test/count-runner-post-by-logined-runner-and-review-status/response-fields.adoc[]

==== *리뷰 지원한 서포터 조회 API*

===== *Http Request*
Expand Down Expand Up @@ -94,7 +116,29 @@ include::{snippets}/../../build/generated-snippets/runner-post-read-with-logined

include::{snippets}/../../build/generated-snippets/runner-post-read-with-logined-supporter-api-test/read-runner-post-by-logined-supporter-and-review-status/response-fields.adoc[]

==== *서포터 리뷰 완료한 게시글 조회 API*
==== *서포터 마이페이지 게시글 개수 조회 API*

===== *Http Request*

include::{snippets}/../../build/generated-snippets/runner-post-count-with-logined-supporter-api-test/count-runner-post-by-logined-supporter-and-review-status/http-request.adoc[]

===== *Http Request Headers*

include::{snippets}/../../build/generated-snippets/runner-post-count-with-logined-supporter-api-test/count-runner-post-by-logined-supporter-and-review-status/request-headers.adoc[]

===== *Http Request Query Parameters*

include::{snippets}/../../build/generated-snippets/runner-post-count-with-logined-supporter-api-test/count-runner-post-by-logined-supporter-and-review-status/query-parameters.adoc[]

===== *Http Response*

include::{snippets}/../../build/generated-snippets/runner-post-count-with-logined-supporter-api-test/count-runner-post-by-logined-supporter-and-review-status/http-response.adoc[]

===== *Http Response Fields*

include::{snippets}/../../build/generated-snippets/runner-post-count-with-logined-supporter-api-test/count-runner-post-by-logined-supporter-and-review-status/response-fields.adoc[]

==== *서포터의 리뷰 완료한 게시글 조회 API*

===== *Http Request*

Expand All @@ -112,6 +156,24 @@ include::{snippets}/../../build/generated-snippets/runner-post-read-of-supporter

include::{snippets}/../../build/generated-snippets/runner-post-read-of-supporter-by-guest-api-test/read-runner-post-by-supporter-id-and-review-status/response-fields.adoc[]

==== *서포터의 리뷰 완료한 게시글 개수 조회 API*

===== *Http Request*

include::{snippets}/../../build/generated-snippets/runner-post-count-of-supporter-by-guest-api-test/count-runner-post-by-supporter-id-and-review-status/http-request.adoc[]

===== *Http Request Query Parameters*

include::{snippets}/../../build/generated-snippets/runner-post-count-of-supporter-by-guest-api-test/count-runner-post-by-supporter-id-and-review-status/query-parameters.adoc[]

===== *Http Response*

include::{snippets}/../../build/generated-snippets/runner-post-count-of-supporter-by-guest-api-test/count-runner-post-by-supporter-id-and-review-status/http-response.adoc[]

===== *Http Response Fields*

include::{snippets}/../../build/generated-snippets/runner-post-count-of-supporter-by-guest-api-test/count-runner-post-by-supporter-id-and-review-status/response-fields.adoc[]

==== *태그 이름과 리뷰 상태를 조건으로 러너 게시글 페이징 조회 API*

===== *Http Request*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
package touch.baton.domain.member.command.repository;

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.member.command.SupporterRunnerPost;

import java.util.Optional;

public interface SupporterRunnerPostCommandRepository extends JpaRepository<SupporterRunnerPost, Long> {

@Query("""
select count(1)
from SupporterRunnerPost srp
group by srp.runnerPost.id
having srp.runnerPost.id = :runnerPostId
""")
Optional<Long> countByRunnerPostId(@Param("runnerPostId") final Long runnerPostId);

boolean existsByRunnerPostId(final Long runnerPostId);

boolean existsByRunnerPostIdAndSupporterId(final Long runnerPostId, final Long supporterId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@

public interface SupporterRunnerPostQueryRepository extends JpaRepository<SupporterRunnerPost, Long> {

@Query("""
select count(1)
from SupporterRunnerPost srp
group by srp.runnerPost.id
having srp.runnerPost.id in (:runnerPostIds)
""")
List<Long> countByRunnerPostIdIn(@Param("runnerPostIds") final List<Long> runnerPostIds);

@Query("""
select count(1)
from SupporterRunnerPost srp
Expand All @@ -26,20 +18,6 @@ select count(1)
""")
Optional<Long> countByRunnerPostId(@Param("runnerPostId") final Long runnerPostId);

@Query("""
select case when exists (
select 1 from SupporterRunnerPost srp
where srp.runnerPost.id = rp.id)
then (
select count(srp.id) from SupporterRunnerPost srp
where srp.runnerPost.id = rp.id
) else 0 end
from RunnerPost rp
where rp.id in :runnerPostIds
order by rp.id desc
""")
List<Long> countByRunnerPostIds(@Param("runnerPostIds") final List<Long> runnerPostIds);

@Query("""
select (count(1) >= 1)
from SupporterRunnerPost srp
Expand All @@ -49,11 +27,13 @@ select count(srp.id) from SupporterRunnerPost srp
""")
boolean existsByRunnerPostIdAndMemberId(@Param("runnerPostId") final Long runnerPostId, @Param("memberId") final Long memberId);

boolean existsByRunnerPostId(final Long runnerPostId);

void deleteBySupporterIdAndRunnerPostId(final Long supporterId, final Long runnerPostId);

boolean existsByRunnerPostIdAndSupporterId(final Long runnerPostId, final Long supporterId);

List<SupporterRunnerPost> readByRunnerPostId(final Long runnerPostId);

@Query("""
select count(1)
from SupporterRunnerPost srp
join fetch RunnerPost rp on rp.id = srp.runnerPost.id
where rp.reviewStatus = 'NOT_STARTED' and srp.supporter.id = :supporterId
""")
long countRunnerPostBySupporterIdByReviewStatusNotStarted(@Param("supporterId") final Long supporterId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,7 @@ public Long createRunnerPostApplicant(final Supporter supporter,
final Long runnerPostId
) {
final RunnerPost foundRunnerPost = getRunnerPostOrThrowException(runnerPostId);
final boolean isApplicantHistoryExist = supporterRunnerPostCommandRepository.existsByRunnerPostIdAndSupporterId(runnerPostId, supporter.getId());
if (isApplicantHistoryExist) {
if (isApplySupporter(foundRunnerPost, supporter)) {
throw new RunnerPostBusinessException("Supporter 는 이미 해당 RunnerPost 에 리뷰 신청을 한 이력이 있습니다.");
}

Expand Down Expand Up @@ -160,7 +159,7 @@ public void updateRunnerPostAppliedSupporter(final Runner runner,
final RunnerPost foundRunnerPost = runnerPostCommandRepository.findById(runnerPostId)
.orElseThrow(() -> new RunnerPostBusinessException("RunnerPost 의 식별자값으로 러너 게시글을 조회할 수 없습니다."));

if (isApplySupporter(runnerPostId, foundApplySupporter)) {
if (!isApplySupporter(foundRunnerPost, foundApplySupporter)) {
throw new RunnerPostBusinessException("게시글에 리뷰를 제안한 서포터가 아닙니다.");
}
if (foundRunnerPost.isNotOwner(runner)) {
Expand All @@ -172,7 +171,7 @@ public void updateRunnerPostAppliedSupporter(final Runner runner,
eventPublisher.publishEvent(new RunnerPostAssignSupporterEvent(foundRunnerPost.getId()));
}

private boolean isApplySupporter(final Long runnerPostId, final Supporter foundSupporter) {
return !supporterRunnerPostCommandRepository.existsByRunnerPostIdAndSupporterId(runnerPostId, foundSupporter.getId());
private boolean isApplySupporter(final RunnerPost runnerPost, final Supporter supporter) {
return supporterRunnerPostCommandRepository.existsByRunnerPostIdAndSupporterId(runnerPost.getId(), supporter.getId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public ResponseEntity<RunnerPostResponse.Detail> readByRunnerPostId(
@PathVariable final Long runnerPostId
) {
final RunnerPost foundRunnerPost = runnerPostQueryService.readByRunnerPostId(runnerPostId);
final long applicantCount = runnerPostQueryService.readCountByRunnerPostId(foundRunnerPost.getId());
final long applicantCount = runnerPostQueryService.countApplicantsByRunnerPostId(foundRunnerPost.getId());
final boolean isApplicantHistoryExist = runnerPostQueryService.existsRunnerPostApplicantByRunnerPostIdAndMemberId(runnerPostId, member.getId());

runnerPostQueryService.increaseWatchedCount(foundRunnerPost);
Expand All @@ -70,6 +70,14 @@ public ResponseEntity<PageResponse<RunnerPostResponse.Simple>> readRunnerPostByS
return ResponseEntity.ok(runnerPostQueryService.pageRunnerPostBySupporterIdAndReviewStatus(pageParams, supporterId, ReviewStatus.DONE));
}

@GetMapping("/search/count")
public ResponseEntity<RunnerPostResponse.Count> countRunnerPostBySupporterIdAndReviewStatusDone(
@RequestParam final Long supporterId
) {
final long count = runnerPostQueryService.countRunnerPostBySupporterIdAndReviewStatus(supporterId, ReviewStatus.DONE);
return ResponseEntity.ok(RunnerPostResponse.Count.from(count));
}

@GetMapping("/{runnerPostId}/supporters")
public ResponseEntity<SupporterRunnerPostResponses.Detail> readSupporterRunnerPostsByRunnerPostId(
@AuthRunnerPrincipal final Runner runner,
Expand All @@ -91,11 +99,30 @@ public ResponseEntity<PageResponse<RunnerPostResponse.Simple>> readRunnerPostByL
return ResponseEntity.ok(runnerPostQueryService.pageRunnerPostBySupporterIdAndReviewStatus(pageParams, supporter.getId(), reviewStatus));
}

@GetMapping("/me/runner") public ResponseEntity<PageResponse<RunnerPostResponse.SimpleByRunner>> readRunnerPostByLoginedRunnerAndReviewStatus(
@GetMapping("/me/runner")
public ResponseEntity<PageResponse<RunnerPostResponse.SimpleByRunner>> readRunnerPostByLoginedRunnerAndReviewStatus(
@AuthRunnerPrincipal final Runner runner,
@Valid @ModelAttribute final PageParams pageParams,
@RequestParam(required = false) final ReviewStatus reviewStatus
) {
return ResponseEntity.ok(runnerPostQueryService.pageRunnerPostByRunnerIdAndReviewStatus(pageParams, runner.getId(), reviewStatus));
}

@GetMapping("/me/supporter/count")
public ResponseEntity<RunnerPostResponse.Count> countRunnerPostByLoginedSupporterAndReviewStatus(
@AuthSupporterPrincipal final Supporter supporter,
@RequestParam final ReviewStatus reviewStatus
) {
final long runnerPostCount = runnerPostQueryService.countRunnerPostBySupporterIdAndReviewStatus(supporter.getId(), reviewStatus);
return ResponseEntity.ok(RunnerPostResponse.Count.from(runnerPostCount));
}

@GetMapping("/me/runner/count")
public ResponseEntity<RunnerPostResponse.Count> countRunnerPostByLoginedRunnerAndReviewStatus(
@AuthRunnerPrincipal final Runner runner,
@RequestParam final ReviewStatus reviewStatus
) {
final long runnerPostCount = runnerPostQueryService.countRunnerPostByRunnerIdAndReviewStatus(runner.getId(), reviewStatus);
return ResponseEntity.ok(RunnerPostResponse.Count.from(runnerPostCount));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ public Long extractId() {
}
}

public record Count(Long count) {

public static Count from(final long count) {
return new Count(count);
}
}

private static List<String> convertToTags(final RunnerPost runnerPost) {
return runnerPost.getRunnerPostTags()
.getRunnerPostTags()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.springframework.data.repository.query.Param;
import touch.baton.domain.runnerpost.command.RunnerPost;
import touch.baton.domain.runnerpost.command.repository.dto.RunnerPostApplicantCountDto;
import touch.baton.domain.runnerpost.command.vo.ReviewStatus;

import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -39,4 +40,18 @@ public interface RunnerPostQueryRepository extends JpaRepository<RunnerPost, Lon
group by rp.id
""")
List<RunnerPostApplicantCountDto> countApplicantsByRunnerPostIds(@Param("runnerPostIds") final List<Long> runnerPostIds);

@Query("""
select count(1)
from RunnerPost rp
where rp.runner.id = :runnerId and rp.reviewStatus = :reviewStatus
""")
long countByRunnerIdAndReviewStatus(@Param("runnerId") final Long runnerId, @Param("reviewStatus") final ReviewStatus reviewStatus);

@Query("""
select count(1)
from RunnerPost rp
where rp.supporter.id = :supporterId and rp.reviewStatus = :reviewStatus
""")
long countBySupporterIdAndReviewStatus(@Param("supporterId") final Long supporterId, @Param("reviewStatus") final ReviewStatus reviewStatus);
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,21 @@ public boolean existsRunnerPostApplicantByRunnerPostIdAndMemberId(final Long run
return supporterRunnerPostQueryRepository.existsByRunnerPostIdAndMemberId(runnerPostId, memberId);
}

public long readCountByRunnerPostId(final Long runnerPostId) {
public long countApplicantsByRunnerPostId(final Long runnerPostId) {
return supporterRunnerPostQueryRepository.countByRunnerPostId(runnerPostId).orElse(0L);
}

public long countRunnerPostByRunnerIdAndReviewStatus(final Long runnerId, final ReviewStatus reviewStatus) {
return runnerPostQueryRepository.countByRunnerIdAndReviewStatus(runnerId, reviewStatus);
}

public long countRunnerPostBySupporterIdAndReviewStatus(final Long supporterId, final ReviewStatus reviewStatus) {
if (reviewStatus.isNotStarted()) {
return supporterRunnerPostQueryRepository.countRunnerPostBySupporterIdByReviewStatusNotStarted(supporterId);
}
return runnerPostQueryRepository.countBySupporterIdAndReviewStatus(supporterId, reviewStatus);
}

@Transactional
public void increaseWatchedCount(final RunnerPost runnerPost) {
runnerPost.increaseWatchedCount();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import touch.baton.domain.member.query.repository.SupporterRunnerPostQueryRepository;

@Profile("test")

public interface TestSupporterRunnerPostQueryRepository extends SupporterRunnerPostQueryRepository {

default Long getApplicantCountByRunnerPostId(final Long runnerPostId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package touch.baton.assure.runnerpost.query.count.runner;

import org.junit.jupiter.api.Test;
import touch.baton.assure.runnerpost.support.command.RunnerPostCreateSupport;
import touch.baton.assure.runnerpost.support.query.count.runner.RunnerPostCountByRunnerSupport;
import touch.baton.config.AssuredTestConfig;
import touch.baton.config.infra.auth.oauth.authcode.FakeAuthCodes;
import touch.baton.domain.runnerpost.command.vo.ReviewStatus;
import touch.baton.domain.runnerpost.query.controller.response.RunnerPostResponse;

import java.time.LocalDateTime;
import java.util.List;

import static touch.baton.assure.runnerpost.support.command.RunnerPostCreateSupport.러너_게시글_생성_요청;
import static touch.baton.assure.runnerpost.support.query.count.runner.RunnerPostCountByRunnerSupport.러너_게시글_개수_응답;

@SuppressWarnings("NonAsciiCharacters")
class RunnerPostCountByRunnerAssuredTest extends AssuredTestConfig {

@Test
void 로그인한_러너와_연관된_러너_게시글_개수_조회에_성공한다() {
// given
final String 디투_액세스_토큰 = oauthLoginTestManager.소셜_회원가입을_진행한_후_액세스_토큰을_반환한다(FakeAuthCodes.ditooAuthCode());
final String 헤나_액세스_토큰 = oauthLoginTestManager.소셜_회원가입을_진행한_후_액세스_토큰을_반환한다(FakeAuthCodes.hyenaAuthCode());
러너_게시글_생성에_성공한다(디투_액세스_토큰);
러너_게시글_생성에_성공한다(헤나_액세스_토큰);

// when
final RunnerPostResponse.Count 기대된_러너_게시글_개수 = 러너_게시글_개수_응답(1);

// then
RunnerPostCountByRunnerSupport
.클라이언트_요청()
.액세스_토큰으로_로그인한다(디투_액세스_토큰)
.리뷰_상태로_로그인한_러너와_연관된_러너_게시글_개수를_조회한다(ReviewStatus.NOT_STARTED)

.서버_응답()
.로그인한_러너와_연관된_러너_게시글_개수_조회_성공을_검증한다(기대된_러너_게시글_개수);
}

private void 러너_게시글_생성에_성공한다(final String 액세스_토큰) {
RunnerPostCreateSupport
.클라이언트_요청()
.액세스_토큰으로_로그인한다(액세스_토큰)
.러너_게시글_등록_요청한다(
러너_게시글_생성_요청(
"테스트용_러너_게시글_제목",
List.of("자바", "스프링"),
"https://test-pull-request.com",
LocalDateTime.now().plusHours(100),
"테스트용_러너_게시글_구현_내용",
"테스트용_러너_게시글_궁금한_내용",
"테스트용_러너_게시글_참고_사항"
)
)

.서버_응답()
.러너_게시글_생성_성공을_검증한다();
}
}
Loading