-
Notifications
You must be signed in to change notification settings - Fork 4
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
[BE] 제출한 인원 조회하는 기능 구현하기 #579
Changes from 3 commits
23c65b0
8611879
9e0a46f
eca1857
00920e1
b97ecf5
2583d38
ae692fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,28 @@ | ||
package harustudy.backend.view.controller; | ||
|
||
import harustudy.backend.auth.Authenticated; | ||
import harustudy.backend.auth.dto.AuthMember; | ||
import harustudy.backend.view.dto.SubmittersResponse; | ||
import harustudy.backend.view.service.PollingService; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.stereotype.Controller; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
|
||
@RequiredArgsConstructor | ||
@Controller | ||
public class PollingController { | ||
|
||
private final PollingService pollingService; | ||
|
||
@Operation(summary = "스터디원 별 제출 여부 조회") | ||
@GetMapping("/api/submitted") | ||
public ResponseEntity<SubmittersResponse> findSubmitters( | ||
@Authenticated AuthMember authMember, | ||
@RequestParam Long studyId | ||
) { | ||
return ResponseEntity.ok(pollingService.findSubmitters(studyId)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package harustudy.backend.view.dto; | ||
|
||
public record SubmitterResponse(String nickname, Boolean submitted) { | ||
|
||
public static SubmitterResponse of(String nickname, Boolean submitted) { | ||
return new SubmitterResponse(nickname, submitted); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package harustudy.backend.view.dto; | ||
|
||
import java.util.List; | ||
|
||
public record SubmittersResponse(List<SubmitterResponse> status) { | ||
|
||
public static SubmittersResponse from(List<SubmitterResponse> submitterResponses) { | ||
return new SubmittersResponse(submitterResponses); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package harustudy.backend.view.exception; | ||
|
||
import harustudy.backend.common.exception.HaruStudyException; | ||
|
||
public class CurrentCycleContentNotExistsException extends HaruStudyException { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ExceptionMapper 추가 됐나요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이건 클라까지 안 나가는 예외라 괜찮지 않을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #580 으로 이슈 파뒀습니다! |
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package harustudy.backend.view.exception; | ||
|
||
import harustudy.backend.common.exception.HaruStudyException; | ||
|
||
public class SubmitNotAllowedStepException extends HaruStudyException { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ExceptionMapper 추가 됐나요? |
||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,49 @@ | ||
package harustudy.backend.view.service; | ||
|
||
import harustudy.backend.content.domain.Content; | ||
import harustudy.backend.participant.domain.Participant; | ||
import harustudy.backend.participant.repository.ParticipantRepository; | ||
import harustudy.backend.study.domain.Study; | ||
import harustudy.backend.study.repository.StudyRepository; | ||
import harustudy.backend.view.dto.SubmitterResponse; | ||
import harustudy.backend.view.dto.SubmittersResponse; | ||
import harustudy.backend.view.exception.CurrentCycleContentNotExistsException; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
@RequiredArgsConstructor | ||
@Service | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. merge할 때 트랜잭션 설정 추가해줘야겠네용 |
||
public class PollingService { | ||
|
||
private final StudyRepository studyRepository; | ||
private final ParticipantRepository participantRepository; | ||
|
||
public SubmittersResponse findSubmitters(Long studyId) { | ||
Study study = studyRepository.findByIdIfExists(studyId); | ||
List<Participant> participants = participantRepository.findByStudy(study); | ||
return generateSubmitterResponses(study, participants); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 제가 구현한것도 마찬가지로 일단 구현 해놓고 최적화를 고려해야겠네요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 나중에 fetch join 하죠 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 최적화할게 많겠네요 |
||
|
||
private SubmittersResponse generateSubmitterResponses(Study study, List<Participant> participants) { | ||
List<SubmitterResponse> submitterResponses = new ArrayList<>(); | ||
|
||
for (Participant participant : participants) { | ||
Content currentCycleContent = extractCurrentCycleContent(study, participant); | ||
|
||
submitterResponses.add(SubmitterResponse.of( | ||
participant.getNickname(), | ||
SubmitterCheckingStrategy.isSubmitted(study.getStep(), currentCycleContent))); | ||
} | ||
return SubmittersResponse.from(submitterResponses); | ||
} | ||
|
||
private Content extractCurrentCycleContent(Study study, Participant participant) { | ||
return participant.getContents().stream() | ||
.filter(content -> content.hasSameCycleWith(study)) | ||
.findFirst() | ||
.orElseThrow(CurrentCycleContentNotExistsException::new); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package harustudy.backend.view.service; | ||
|
||
import harustudy.backend.content.domain.Content; | ||
import harustudy.backend.participant.domain.Step; | ||
import harustudy.backend.view.exception.SubmitNotAllowedStepException; | ||
|
||
import java.util.Arrays; | ||
import java.util.function.Function; | ||
|
||
public enum SubmitterCheckingStrategy { | ||
|
||
PLANNING(Step.PLANNING, Content::isPlanWritten), | ||
RETROSPECT(Step.RETROSPECT, Content::isRetrospectWritten); | ||
|
||
private final Step step; | ||
private final Function<Content, Boolean> strategy; | ||
|
||
SubmitterCheckingStrategy(Step step, Function<Content, Boolean> strategy) { | ||
this.step = step; | ||
this.strategy = strategy; | ||
} | ||
|
||
public static boolean isSubmitted(Step step, Content content) { | ||
return Arrays.stream(values()) | ||
.filter(each -> each.step.equals(step)) | ||
.map(each -> each.strategy) | ||
.findFirst() | ||
.orElseThrow(SubmitNotAllowedStepException::new) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 예외의 의미는 무엇인가요? |
||
.apply(content); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
package harustudy.backend.view.service; | ||
|
||
import harustudy.backend.content.domain.Content; | ||
import harustudy.backend.member.domain.LoginType; | ||
import harustudy.backend.member.domain.Member; | ||
import harustudy.backend.participant.domain.Participant; | ||
import harustudy.backend.study.domain.Study; | ||
import harustudy.backend.view.dto.SubmitterResponse; | ||
import harustudy.backend.view.dto.SubmittersResponse; | ||
import harustudy.backend.view.exception.SubmitNotAllowedStepException; | ||
import jakarta.persistence.EntityManager; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.DisplayNameGeneration; | ||
import org.junit.jupiter.api.DisplayNameGenerator; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
|
||
@SuppressWarnings("NonAsciiCharacters") | ||
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) | ||
@Transactional | ||
@SpringBootTest | ||
class PollingServiceTest { | ||
|
||
@Autowired | ||
private EntityManager entityManager; | ||
|
||
@Autowired | ||
private PollingService pollingService; | ||
|
||
private Study study; | ||
private Content content1; | ||
private Content content2; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
study = new Study("study", 1, 20); | ||
Member member1 = new Member("name1", "email", "imageUrl", LoginType.GUEST); | ||
Member member2 = new Member("name2", "email", "imageUrl", LoginType.GUEST); | ||
Participant participant1 = new Participant(study, member1, "nickname1"); | ||
Participant participant2 = new Participant(study, member2, "nickname2"); | ||
content1 = new Content(participant1, 1); | ||
content2 = new Content(participant2, 1); | ||
|
||
entityManager.persist(study); | ||
entityManager.persist(member1); | ||
entityManager.persist(member2); | ||
entityManager.persist(participant1); | ||
entityManager.persist(participant2); | ||
entityManager.persist(content1); | ||
entityManager.persist(content2); | ||
} | ||
|
||
@Test | ||
void 대기_상태에서_제출_인원을_확인하려_하면_예외가_발생한다() { | ||
// given, when, then | ||
entityManager.flush(); | ||
entityManager.clear(); | ||
|
||
assertThatThrownBy(() -> pollingService.findSubmitters(study.getId())) | ||
.isInstanceOf(SubmitNotAllowedStepException.class); | ||
} | ||
|
||
@Test | ||
void 계획_단계에서는_제출_인원을_확인할_수_있다() { | ||
study.proceed(); | ||
content1.changePlan(Map.of("content", "written")); | ||
|
||
entityManager.flush(); | ||
entityManager.clear(); | ||
|
||
// when | ||
SubmittersResponse submitters = pollingService.findSubmitters(study.getId()); | ||
|
||
// then | ||
SubmittersResponse expected = new SubmittersResponse(List.of( | ||
new SubmitterResponse("nickname1", true), | ||
new SubmitterResponse("nickname2", false) | ||
)); | ||
|
||
assertThat(submitters).usingRecursiveComparison() | ||
.isEqualTo(expected); | ||
} | ||
|
||
@Test | ||
void 진행_단계에서는_제출_인원을_확인하려_하면_예외가_발생한다() { | ||
// given | ||
study.proceed(); | ||
study.proceed(); | ||
|
||
entityManager.flush(); | ||
entityManager.clear(); | ||
|
||
// when, then | ||
assertThatThrownBy(() -> pollingService.findSubmitters(study.getId())) | ||
.isInstanceOf(SubmitNotAllowedStepException.class); | ||
} | ||
|
||
@Test | ||
void 회고_단계에서는_제출_인원을_확인할_수_있다() { | ||
study.proceed(); | ||
study.proceed(); | ||
study.proceed(); | ||
content1.changeRetrospect(Map.of("content", "written")); | ||
content2.changeRetrospect(Map.of("content", "written")); | ||
|
||
entityManager.flush(); | ||
entityManager.clear(); | ||
|
||
// when | ||
SubmittersResponse submitters = pollingService.findSubmitters(study.getId()); | ||
|
||
// then | ||
SubmittersResponse expected = new SubmittersResponse(List.of( | ||
new SubmitterResponse("nickname1", true), | ||
new SubmitterResponse("nickname2", true) | ||
)); | ||
|
||
assertThat(submitters).usingRecursiveComparison() | ||
.isEqualTo(expected); | ||
} | ||
|
||
@Test | ||
void 스터디가_종료한_뒤에는_제출_인원을_확인하려_하면_예외가_발생한다() { | ||
// given | ||
study.proceed(); | ||
study.proceed(); | ||
study.proceed(); | ||
study.proceed(); | ||
|
||
entityManager.flush(); | ||
entityManager.clear(); | ||
|
||
// when, then | ||
assertThatThrownBy(() -> pollingService.findSubmitters(study.getId())) | ||
.isInstanceOf(SubmitNotAllowedStepException.class); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RestController이어야 할 것 같지만 어차피 머지할때 해결할 것 같습니다