Skip to content

Commit

Permalink
Feature/#171 팀 스터디 상세조회에 leader 정보를 추가한다 (#176)
Browse files Browse the repository at this point in the history
* feat: 팀 상세조회에 teamLeaderId 정보 추가

* test: 팀 상세조회 테스트에 teamLeaderId 정보 추가

* feat: study상세조회에 studyLeaderId 추가

* test: study상세조회 테스트에 studyLeaderId 추가
  • Loading branch information
JJimini authored Jun 29, 2024
1 parent 4b76e51 commit da5d31e
Show file tree
Hide file tree
Showing 12 changed files with 100 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
import doore.member.domain.StudyRoleType;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

public interface StudyRoleRepository extends JpaRepository<StudyRole, Long> {
Optional<StudyRole> findStudyRoleByStudyIdAndMemberId(Long studyId, Long memberId);
Optional<StudyRole> findStudyRoleByStudyIdAndStudyRoleType(Long studyId, StudyRoleType studyRoleType);
@Query("SELECT sr.memberId FROM StudyRole sr WHERE sr.studyId = :studyId AND sr.studyRoleType = 'ROLE_스터디장'")
Long findLeaderIdByStudyId(Long studyId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import doore.member.domain.TeamRoleType;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

public interface TeamRoleRepository extends JpaRepository<TeamRole, Long> {
Optional<TeamRole> findTeamRoleByTeamIdAndMemberId(Long teamId, Long memberId);
Optional<TeamRole> findTeamRoleByTeamIdAndTeamRoleType(Long teamId, TeamRoleType teamRoleType);
Optional<TeamRole> findTeamRoleByMemberId(Long memberId);
@Query("SELECT tr.memberId FROM TeamRole tr WHERE tr.teamId = :teamId AND tr.teamRoleType = 'ROLE_팀장'")
Long findLeaderIdByTeamId(Long teamId);
}
5 changes: 3 additions & 2 deletions src/main/java/doore/study/api/StudyController.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import doore.study.application.StudyQueryService;
import doore.study.application.dto.request.StudyCreateRequest;
import doore.study.application.dto.request.StudyUpdateRequest;
import doore.study.application.dto.response.StudyReferenceResponse;
import doore.study.application.dto.response.StudyResponse;
import jakarta.validation.Valid;
import java.util.List;
Expand Down Expand Up @@ -70,8 +71,8 @@ public ResponseEntity<Void> terminateStudy(@PathVariable final Long studyId, @Lo
}

@GetMapping("/studies/members/{memberId}") // 회원
public ResponseEntity<List<StudyResponse>> getMyStudies(@PathVariable final Long memberId,
@LoginMember final Member member) {
public ResponseEntity<List<StudyReferenceResponse>> getMyStudies(@PathVariable final Long memberId,
@LoginMember final Member member) {
// TODO: 3/22/24 토큰의 주인과 회원아이디가 같은지 검증 (2024/5/15 완료)
return ResponseEntity.ok(studyQueryService.findMyStudies(memberId, member.getId()));
}
Expand Down
12 changes: 5 additions & 7 deletions src/main/java/doore/study/application/StudyQueryService.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import doore.member.domain.repository.ParticipantRepository;
import doore.member.domain.repository.StudyRoleRepository;
import doore.member.exception.MemberException;
import doore.study.application.dto.response.StudyReferenceResponse;
import doore.study.application.dto.response.StudyResponse;
import doore.study.domain.Study;
import doore.study.domain.repository.CurriculumItemRepository;
Expand Down Expand Up @@ -47,17 +48,18 @@ public class StudyQueryService {

public StudyResponse findStudyById(final Long studyId) {
final Study study = studyRepository.findById(studyId).orElseThrow(() -> new StudyException(NOT_FOUND_STUDY));
final Long studyLeaderId = studyRoleRepository.findLeaderIdByStudyId(study.getId());

final Team team = teamRepository.findById(study.getTeamId())
.orElseThrow(() -> new TeamException(NOT_FOUND_TEAM));
final Crop crop = cropRepository.findById(study.getCropId())
.orElseThrow(() -> new CropException(NOT_FOUND_CROP));
final long studyProgressRatio = checkStudyProgressRatio(studyId);

return StudyResponse.of(study, team, crop, studyProgressRatio);
return StudyResponse.of(study, team, crop, studyProgressRatio, studyLeaderId);
}

public List<StudyResponse> findMyStudies(final Long memberId, final Long tokenMemberId) {
public List<StudyReferenceResponse> findMyStudies(final Long memberId, final Long tokenMemberId) {
checkSameMemberIdAndTokenMemberId(memberId, tokenMemberId);

final List<Participant> participants = participantRepository.findByMemberId(memberId);
Expand All @@ -67,11 +69,7 @@ public List<StudyResponse> findMyStudies(final Long memberId, final Long tokenMe
final List<Study> studies = studyRepository.findAllById(studyIds);

return studies.stream()
.map(study -> StudyResponse.of(study,
teamRepository.findById(study.getTeamId()).orElseThrow(() -> new TeamException(NOT_FOUND_TEAM)),
cropRepository.findById(study.getCropId())
.orElseThrow(() -> new CropException(NOT_FOUND_CROP)),
checkStudyProgressRatio(study.getId())))
.map(study -> StudyReferenceResponse.of(study, checkStudyProgressRatio(study.getId())))
.toList();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package doore.study.application.dto.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import doore.study.domain.Study;
import doore.study.domain.StudyStatus;
import java.time.LocalDate;
import lombok.Builder;

@Builder
public record StudyReferenceResponse(
Long id,
String name,
String description,
@JsonFormat(pattern = "yyyy-MM-dd")
LocalDate startDate,
@JsonFormat(pattern = "yyyy-MM-dd")
LocalDate endDate,
StudyStatus status,
Long cropId,
long studyProgressRatio
) {

public static StudyReferenceResponse of(final Study study, final long studyProgressRatio) {
return new StudyReferenceResponse(study.getId(), study.getName(), study.getDescription(), study.getStartDate(),
study.getEndDate(), study.getStatus(), study.getCropId(), studyProgressRatio);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ public record StudyResponse(
StudyStatus status,
TeamReferenceResponse teamReference,
CropReferenceResponse cropReference,
long studyProgressRatio
long studyProgressRatio,
Long studyLeaderId

) {
public static StudyResponse of(final Study study, final Team team, final Crop crop, final long studyProgressRatio) {
public static StudyResponse of(final Study study, final Team team, final Crop crop, final long studyProgressRatio,
final Long studyLeaderId) {
return StudyResponse.builder()
.id(study.getId())
.name(study.getName())
Expand All @@ -36,6 +38,7 @@ public static StudyResponse of(final Study study, final Team team, final Crop cr
.teamReference(TeamReferenceResponse.from(team))
.cropReference(CropReferenceResponse.from(crop))
.studyProgressRatio(studyProgressRatio)
.studyLeaderId(studyLeaderId)
.build();
}
}
5 changes: 4 additions & 1 deletion src/main/java/doore/team/application/TeamQueryService.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import doore.member.domain.MemberTeam;
import doore.member.domain.repository.MemberRepository;
import doore.member.domain.repository.MemberTeamRepository;
import doore.member.domain.repository.TeamRoleRepository;
import doore.member.exception.MemberException;
import doore.study.application.dto.response.StudyNameResponse;
import doore.study.domain.repository.StudyRepository;
Expand All @@ -37,6 +38,7 @@ public class TeamQueryService {
private final StudyRepository studyRepository;
private final AttendanceRepository attendanceRepository;
private final MemberTeamRepository memberTeamRepository;
private final TeamRoleRepository teamRoleRepository;
private final GardenQueryService gardenQueryService;

public List<TeamReferenceResponse> findMyTeams(final Long memberId, final Long tokenMemberId) {
Expand Down Expand Up @@ -75,8 +77,9 @@ public TeamResponse findTeamByTeamId(final Long teamId) {
final long countAttendanceMemberTeam = attendances.size();
final long attendanceRatio =
countMemberTeam > 0 ? (long) ((countAttendanceMemberTeam * 100.0) / countMemberTeam) : 0;
final Long teamLeaderId = teamRoleRepository.findLeaderIdByTeamId(teamId);

return TeamResponse.of(team, attendanceRatio);
return TeamResponse.of(team, attendanceRatio, teamLeaderId);
}

private void validateMember(final Long memberId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ public record TeamResponse(
String name,
String description,
String imageUrl,
long attendanceRatio
long attendanceRatio,
Long teamLeaderId
) {
public static TeamResponse of(final Team team, final long attendanceRatio) {
public static TeamResponse of(final Team team, final long attendanceRatio, final Long teamLeaderId) {
return TeamResponse.builder()
.id(team.getId())
.name(team.getName())
.description(team.getDescription())
.imageUrl(team.getImageUrl())
.attendanceRatio(attendanceRatio)
.teamLeaderId(teamLeaderId)
.build();
}
}
29 changes: 19 additions & 10 deletions src/test/java/doore/restdocs/docs/StudyApiDocsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import doore.restdocs.RestDocsTest;
import doore.study.application.dto.request.StudyCreateRequest;
import doore.study.application.dto.request.StudyUpdateRequest;
import doore.study.application.dto.response.StudyReferenceResponse;
import doore.study.application.dto.response.StudyResponse;
import doore.study.domain.StudyStatus;
import doore.team.application.dto.response.TeamReferenceResponse;
Expand Down Expand Up @@ -95,6 +96,20 @@ private StudyResponse getStudyResponse() {
.teamReference(teamReferenceResponse)
.cropReference(cropReferenceResponse)
.studyProgressRatio(50)
.studyLeaderId(1L)
.build();
}

private StudyReferenceResponse getStudyReferenceResponse() {
return StudyReferenceResponse.builder()
.id(1L)
.name("알고리즘")
.description("알고리즘 스터디입니다.")
.startDate(LocalDate.parse("2020-01-01"))
.endDate(LocalDate.parse("2020-01-02"))
.status(StudyStatus.IN_PROGRESS)
.cropId(1L)
.studyProgressRatio(50)
.build();
}

Expand Down Expand Up @@ -170,9 +185,9 @@ private StudyResponse getStudyResponse() {
@DisplayName("나의 스터디 목록을 조회한다.")
public void 나의_스터디_목록을_조회한다() throws Exception {
final Long memberId = 1L;
final List<StudyResponse> response = List.of(
getStudyResponse(),
getStudyResponse()
final List<StudyReferenceResponse> response = List.of(
getStudyReferenceResponse(),
getStudyReferenceResponse()
);

final ResponseFieldsSnippet responseFieldsSnippet = responseFields(
Expand All @@ -182,13 +197,7 @@ private StudyResponse getStudyResponse() {
stringFieldWithPath("[].startDate", "스터디의 시작일"),
stringFieldWithPath("[].endDate", "스터디의 종료일"),
stringFieldWithPath("[].status", "스터디의 진행 상태"),
numberFieldWithPath("[].teamReference.id", "스터디가 속한 팀의 ID"),
stringFieldWithPath("[].teamReference.name", "스터디가 속한 팀의 이름"),
stringFieldWithPath("[].teamReference.description", "스터디가 속한 팀의 설명"),
stringFieldWithPath("[].teamReference.imageUrl", "스터디가 속한 팀의 이미지 url"),
numberFieldWithPath("[].cropReference.id", "스터디의 작물의 ID"),
stringFieldWithPath("[].cropReference.name", "스터디의 작물의 이름"),
stringFieldWithPath("[].cropReference.imageUrl", "스터디의 작물의 이미지 url"),
numberFieldWithPath("[].cropId", "스터디의 작물 ID"),
numberFieldWithPath("[].studyProgressRatio", "스터디 진행률")
);

Expand Down
11 changes: 6 additions & 5 deletions src/test/java/doore/restdocs/docs/TeamApiDocsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ void setUp() {
void 팀_상세목록을_조회한다() throws Exception {
final Long teamId = 1L;

final TeamResponse teamResponse = new TeamResponse(1L, "팀 이름", "팀 설명", "1234", 50);
final TeamResponse teamResponse = new TeamResponse(1L, "팀 이름", "팀 설명", "1234", 50, 1L);
final PathParametersSnippet pathParameters = pathParameters(
parameterWithName("teamId").description("조회하고자 하는 팀 ID")
);
Expand All @@ -257,7 +257,8 @@ void setUp() {
stringFieldWithPath("name", "팀 이름"),
stringFieldWithPath("description", "팀 설명"),
stringFieldWithPath("imageUrl", "이미지 url"),
numberFieldWithPath("attendanceRatio", "출석률")
numberFieldWithPath("attendanceRatio", "출석률"),
numberFieldWithPath("teamLeaderId", "팀장 ID")
);

when(teamQueryService.findTeamByTeamId(teamId)).thenReturn(teamResponse);
Expand All @@ -275,15 +276,15 @@ void setUp() {
final List<TeamRankResponse> teamRankResponses = new ArrayList<>();
final List<DayGardenResponse> gardenResponse = List.of(
DayGardenResponse.builder()
.contributeDate(LocalDate.of(2024,1,1))
.contributeDate(LocalDate.of(2024, 1, 1))
.contributeCount(2)
.build(),
DayGardenResponse.builder()
.contributeDate(LocalDate.of(2024,1,2))
.contributeDate(LocalDate.of(2024, 1, 2))
.contributeCount(1)
.build(),
DayGardenResponse.builder()
.contributeDate(LocalDate.of(2024,1,7))
.contributeDate(LocalDate.of(2024, 1, 7))
.contributeCount(5)
.build()
);
Expand Down
20 changes: 7 additions & 13 deletions src/test/java/doore/study/application/StudyQueryServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
import static doore.member.exception.MemberExceptionType.UNAUTHORIZED;
import static doore.study.CurriculumItemFixture.curriculumItem;
import static doore.study.ParticipantCurriculumItemFixture.participantCurriculumItem;
import static doore.study.StudyFixture.algorithmStudy;
import static doore.study.StudyFixture.createStudy;
import static doore.study.exception.StudyExceptionType.NOT_FOUND_STUDY;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertEquals;

import doore.crop.domain.Crop;
import doore.crop.domain.repository.CropRepository;
import doore.helper.IntegrationTest;
import doore.member.domain.Member;
Expand All @@ -21,7 +21,7 @@
import doore.member.domain.repository.ParticipantRepository;
import doore.member.domain.repository.StudyRoleRepository;
import doore.member.exception.MemberException;
import doore.study.application.dto.response.StudyResponse;
import doore.study.application.dto.response.StudyReferenceResponse;
import doore.study.domain.CurriculumItem;
import doore.study.domain.ParticipantCurriculumItem;
import doore.study.domain.Study;
Expand Down Expand Up @@ -102,22 +102,16 @@ class studyTest {
}

@Test
@Disabled
@DisplayName("[성공] 내가 속한 스터디 목록을 조회할 수 있다.")
void findMyStudies_내가_속한_스터디_목록을_조회할_수_있다_성공() {
// given
final Long tokenMemberId = member.getId();
final Study anotherStudy = studyRepository.save(createStudy());
final Study anotherStudy = studyRepository.save(algorithmStudy());
final Participant participantForStudy = participantRepository.save(
Participant.builder().member(member).studyId(study.getId()).build());
final Participant participantForAnotherStudy = participantRepository.save(
Participant.builder().member(member).studyId(anotherStudy.getId()).build());

final Team teamOfStudy = teamRepository.findById(study.getTeamId()).orElseThrow();
final Team teamOfAnotherStudy = teamRepository.findById(anotherStudy.getTeamId()).orElseThrow();
final Crop cropOfTeam = cropRepository.findById(study.getCropId()).orElseThrow();
final Crop cropOfAnotherTeam = cropRepository.findById(anotherStudy.getCropId()).orElseThrow();

final CurriculumItem curriculumItemForStudy1 = curriculumItemRepository.save(curriculumItem(study));
final CurriculumItem curriculumItemForStudy2 = curriculumItemRepository.save(curriculumItem(study));
final CurriculumItem curriculumItemForAnotherStudy = curriculumItemRepository.save(curriculumItem(anotherStudy));
Expand All @@ -133,11 +127,11 @@ class studyTest {
member.getId());

// when
final List<StudyResponse> expectedResponses = List.of(
StudyResponse.of(study, teamOfStudy, cropOfTeam, 50),
StudyResponse.of(anotherStudy, teamOfAnotherStudy, cropOfAnotherTeam, 0)
final List<StudyReferenceResponse> expectedResponses = List.of(
StudyReferenceResponse.of(study, 50),
StudyReferenceResponse.of(anotherStudy, 0)
);
final List<StudyResponse> actualResponses = studyQueryService.findMyStudies(member.getId(),
final List<StudyReferenceResponse> actualResponses = studyQueryService.findMyStudies(member.getId(),
tokenMemberId);

// then
Expand Down
Loading

0 comments on commit da5d31e

Please sign in to comment.