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

[FEAT] 선택지별 투표 결과 API 호출 시, 기권자 정보도 함께 조회 #211

Merged
merged 9 commits into from
Aug 20, 2024
Merged
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ddangkong.domain.room.balance.roomvote;

import ddangkong.domain.balance.content.BalanceContent;
import ddangkong.domain.balance.option.BalanceOption;
import ddangkong.domain.room.Room;
import ddangkong.domain.room.member.Member;
Expand All @@ -10,6 +11,8 @@ public interface RoomBalanceVoteRepository extends JpaRepository<RoomBalanceVote

List<RoomBalanceVote> findByMemberRoomAndBalanceOption(Room room, BalanceOption balanceOption);

List<RoomBalanceVote> findByMemberRoomAndBalanceOptionBalanceContent(Room room, BalanceContent balanceContent);

long countByMemberInAndBalanceOptionIn(List<Member> members, List<BalanceOption> balanceOptions);

List<RoomBalanceVote> findByMemberRoom(Room room);
Expand Down
18 changes: 18 additions & 0 deletions backend/src/main/java/ddangkong/domain/room/member/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import java.util.Objects;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand Down Expand Up @@ -45,4 +46,21 @@ public static Member createMaster(String nickname, Room room) {
public static Member createCommon(String nickname, Room room) {
return new Member(nickname, room, false);
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Member member = (Member) o;
return Objects.equals(id, member.id);
}

@Override
public int hashCode() {
return Objects.hash(id);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ddangkong.facade.balance.vote.dto;

import ddangkong.domain.room.member.Member;
import java.util.List;

public record GiveUpVoteMemberResponse(
List<String> members,
int memberCount) {

public static GiveUpVoteMemberResponse create(List<Member> giveUpMembers) {
List<String> members = giveUpMembers.stream()
.map(Member::getNickname)
.toList();
int memberCount = giveUpMembers.size();

return new GiveUpVoteMemberResponse(members, memberCount);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,44 @@ private boolean isVoteFinished(Room room, BalanceContent balanceContent) {
public RoomBalanceVoteResultResponse getAllVoteResult(Long roomId, Long balanceContentId) {
Room room = roomService.getRoom(roomId);
BalanceContent balanceContent = balanceContentService.getBalanceContent(balanceContentId);
if (isVoteFinished(room, balanceContent)) {
BalanceOptions balanceOptions = balanceOptionService.getBalanceOptions(balanceContent);
// todo 기권 추가
ContentRoomBalanceVoteResponse group = getContentRoomBalanceVoteResponse(room, balanceOptions);
ContentTotalBalanceVoteResponse total = getContentTotalBalanceVoteResponse(balanceOptions);
return new RoomBalanceVoteResultResponse(group, total);

if (!isVoteFinished(room, balanceContent)) {
throw new BadRequestException("투표가 끝나지 않아 투표 결과를 조회할 수 없습니다.");
}
throw new BadRequestException("투표가 끝나지 않아 투표 결과를 조회할 수 없습니다.");

BalanceOptions balanceOptions = balanceOptionService.getBalanceOptions(balanceContent);

ContentRoomBalanceVoteResponse group = getContentRoomBalanceVoteResponse(room, balanceOptions, balanceContent);
ContentTotalBalanceVoteResponse total = getContentTotalBalanceVoteResponse(balanceOptions);

return new RoomBalanceVoteResultResponse(group, total);
}

private ContentRoomBalanceVoteResponse getContentRoomBalanceVoteResponse(Room room, BalanceOptions balanceOptions) {
private List<Member> getGiveUpVoteMemberResponse(Room room, BalanceContent balanceContent) {
List<Member> roomMembers = memberService.findRoomMembers(room);
List<RoomBalanceVote> votesInRoomByContent = roomBalanceVoteService.getVotesInRoomByContent(room,
balanceContent);

List<Member> voteMembers = votesInRoomByContent.stream()
.map(RoomBalanceVote::getMember)
.toList();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사소한 의견) 이 부분은 따로 메서드 분리하면 더 좋을 것 같아요!


return roomMembers.stream()
.filter(roomMember -> !voteMembers.contains(roomMember))
.toList();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사소한 의견) 밑에 메서드랑 위치를 바꿔주시면 더 가독성이 좋을것 같아요~


private ContentRoomBalanceVoteResponse getContentRoomBalanceVoteResponse(Room room,
BalanceOptions balanceOptions,
BalanceContent balanceContent) {
List<Member> giveUpMembers = getGiveUpVoteMemberResponse(room, balanceContent);
List<RoomBalanceVote> firstOptionVotes = roomBalanceVoteService
.getVotesInRoom(room, balanceOptions.getFirstOption());
.getVotesInRoomByOption(room, balanceOptions.getFirstOption());
List<RoomBalanceVote> secondOptionVotes = roomBalanceVoteService
.getVotesInRoom(room, balanceOptions.getSecondOption());
return ContentRoomBalanceVoteResponse.create(balanceOptions, firstOptionVotes, secondOptionVotes);
.getVotesInRoomByOption(room, balanceOptions.getSecondOption());

return ContentRoomBalanceVoteResponse.create(balanceOptions, firstOptionVotes, secondOptionVotes,
giveUpMembers);
}

private ContentTotalBalanceVoteResponse getContentTotalBalanceVoteResponse(BalanceOptions balanceOptions) {
Expand Down
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

의견) 해당 사항도 반영해 주실 수 있으실까요? (바쁘시면 제가 하겠습니다...)

  • 그룹 내 투표자가 0명인 경우, 그룹 결과 퍼센트를 0, 0으로 반환
    전체 투표자가 0명인 경우, 전체 결과 퍼센트는 50, 50으로 반환

근거

image
image
image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위 테스크를 '마루' 의견 반영해서 "투표자가 0명인 경우, 그룹 결과 퍼센트를 0, 0으로 반환"하도록 하는 것 확인했습니다~

Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,28 @@
import ddangkong.domain.balance.option.BalanceOption;
import ddangkong.domain.balance.option.BalanceOptions;
import ddangkong.domain.room.balance.roomvote.RoomBalanceVote;
import ddangkong.domain.room.member.Member;
import ddangkong.facade.balance.vote.dto.GiveUpVoteMemberResponse;
import java.util.List;

public record ContentRoomBalanceVoteResponse(
OptionRoomBalanceVoteResponse firstOption,
OptionRoomBalanceVoteResponse secondOption
OptionRoomBalanceVoteResponse secondOption,
GiveUpVoteMemberResponse giveUp
) {

public static ContentRoomBalanceVoteResponse create(BalanceOptions balanceOptions,
List<RoomBalanceVote> firstOptionVotes,
List<RoomBalanceVote> secondOptionVotes) {
List<RoomBalanceVote> secondOptionVotes,
List<Member> giveUpMembers) {
BalanceOption fistOption = balanceOptions.getFirstOption();
BalanceOption secondOption = balanceOptions.getSecondOption();
int contentVoteCount = firstOptionVotes.size() + secondOptionVotes.size();

return new ContentRoomBalanceVoteResponse(
OptionRoomBalanceVoteResponse.create(fistOption, firstOptionVotes, contentVoteCount),
OptionRoomBalanceVoteResponse.create(secondOption, secondOptionVotes, contentVoteCount)
OptionRoomBalanceVoteResponse.create(secondOption, secondOptionVotes, contentVoteCount),
GiveUpVoteMemberResponse.create(giveUpMembers)
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ddangkong.service.room.balance.roomvote;

import ddangkong.domain.balance.content.BalanceContent;
import ddangkong.domain.balance.option.BalanceOption;
import ddangkong.domain.balance.option.BalanceOptions;
import ddangkong.domain.room.Room;
Expand Down Expand Up @@ -47,7 +48,12 @@ public boolean isVoteFinished(List<Member> roomMembers, BalanceOptions balanceOp
}

@Transactional(readOnly = true)
public List<RoomBalanceVote> getVotesInRoom(Room room, BalanceOption balanceOption) {
public List<RoomBalanceVote> getVotesInRoomByOption(Room room, BalanceOption balanceOption) {
return roomVoteRepository.findByMemberRoomAndBalanceOption(room, balanceOption);
}

@Transactional(readOnly = true)
public List<RoomBalanceVote> getVotesInRoomByContent(Room room, BalanceContent balanceContent) {
return roomVoteRepository.findByMemberRoomAndBalanceOptionBalanceContent(room, balanceContent);
}
Comment on lines 50 to +58
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사소한 의견) 해당 메서드 내부에서 한 번만 조회하는데, @Transactional을 붙인 이유가 있을까요?
(그냥 붙어있으니까 붙인건가?)

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
public class PercentageCalculator {

private static final double SECOND_DECIMAL_PLACE_ROUNDING_FACTOR = 100.0;
private static final int DEFAULT_PERCENTAGE = 50;
private static final int NON_TOTAL_COUNT_PERCENTAGE = 0;

public static int calculatePercent(long count, long totalCount) {
if (count < 0) {
Expand All @@ -19,7 +19,7 @@ public static int calculatePercent(long count, long totalCount) {
}

if (totalCount == 0) {
return DEFAULT_PERCENTAGE;
return NON_TOTAL_COUNT_PERCENTAGE;
}
return (int) Math.round(count * SECOND_DECIMAL_PLACE_ROUNDING_FACTOR / totalCount);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class 밸런스_게임_방_정보_조회 {

//then
assertAll(
() -> Assertions.assertThat(actual.members()).hasSize(4),
() -> Assertions.assertThat(actual.members()).hasSize(5),
() -> Assertions.assertThat(actual.isGameStart()).isTrue(),
() -> Assertions.assertThat(actual.roomSetting().timeLimit()).isEqualTo(30000),
() -> Assertions.assertThat(actual.roomSetting().totalRound()).isEqualTo(5)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import ddangkong.controller.room.balance.roomvote.RoomBalanceVoteController;
import ddangkong.documentation.BaseDocumentationTest;
import ddangkong.facade.balance.vote.dto.ContentTotalBalanceVoteResponse;
import ddangkong.facade.balance.vote.dto.GiveUpVoteMemberResponse;
import ddangkong.facade.balance.vote.dto.OptionTotalBalanceVoteResponse;
import ddangkong.facade.room.balance.roomvote.RoomBalanceVoteFacade;
import ddangkong.facade.room.balance.roomvote.dto.ContentRoomBalanceVoteResponse;
Expand Down Expand Up @@ -58,9 +59,13 @@ class 방_투표_결과_조희 {
List.of("rapper lee"), 1, 25);
OptionTotalBalanceVoteResponse firstTotalResponse = new OptionTotalBalanceVoteResponse(1L, "민초", 50);
OptionTotalBalanceVoteResponse secondTotalResponse = new OptionTotalBalanceVoteResponse(2L, "반민초", 50);
GiveUpVoteMemberResponse giveUpVoteMemberResponse = new GiveUpVoteMemberResponse(List.of("jason"), 1);

RoomBalanceVoteResultResponse response = new RoomBalanceVoteResultResponse(
new ContentRoomBalanceVoteResponse(firstGroupResponse, secondGroupResponse),
new ContentTotalBalanceVoteResponse(firstTotalResponse, secondTotalResponse));
new ContentRoomBalanceVoteResponse(firstGroupResponse, secondGroupResponse,
giveUpVoteMemberResponse),
new ContentTotalBalanceVoteResponse(firstTotalResponse, secondTotalResponse)
);
when(roomBalanceVoteFacade.getAllVoteResult(roomId, contentId)).thenReturn(response);

// when & then
Expand All @@ -77,19 +82,24 @@ class 방_투표_결과_조희 {
fieldWithPath("group.firstOption.optionId").type(NUMBER).description("선택지 ID"),
fieldWithPath("group.firstOption.name").type(STRING).description("선택지 이름"),
fieldWithPath("group.firstOption.members").type(ARRAY)
.description("선택지를 선택한 멤버 이름들"),
.description("선택지를 선택한 멤버들의 닉네임"),
fieldWithPath("group.firstOption.memberCount").type(NUMBER)
.description("선택지를 선택한 사람 수"),
fieldWithPath("group.firstOption.percent").type(NUMBER).description("선택지를 선택한 퍼센트"),
fieldWithPath("group.secondOption").type(OBJECT).description("그룹 내 두 번째 선택지 결과"),
fieldWithPath("group.secondOption.optionId").type(NUMBER).description("선택지 ID"),
fieldWithPath("group.secondOption.name").type(STRING).description("선택지 이름"),
fieldWithPath("group.secondOption.members").type(ARRAY)
.description("선택지를 선택한 멤버 이름들"),
.description("선택지를 선택한 멤버들의 닉네임"),
fieldWithPath("group.secondOption.memberCount").type(NUMBER)
.description("선택지를 선택한 사람 수"),
fieldWithPath("group.secondOption.percent").type(NUMBER)
.description("선택지를 선택한 퍼센트"),
fieldWithPath("group.giveUp").type(OBJECT).description("기권한 멤버 정보"),
fieldWithPath("group.giveUp.members").type(ARRAY)
.description("기권한 멤버들의 닉네임"),
fieldWithPath("group.giveUp.memberCount").type(NUMBER)
.description("기권한 멤버 수"),
fieldWithPath("total").type(OBJECT).description("전체 유저 결과"),
fieldWithPath("total.firstOption").type(OBJECT).description("전체 유저 첫 번째 선택지 결과"),
fieldWithPath("total.firstOption.optionId").type(NUMBER).description("선택지 ID"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class 방_생성 {
void 방_생성_시_방장_멤버를_생성하고_방을_생성한다() {
// given
String nickname = "나는방장";
MemberResponse expectedMemberResponse = new MemberResponse(13L, nickname, true);
MemberResponse expectedMemberResponse = new MemberResponse(14L, nickname, true);

// when
RoomJoinResponse actual = roomFacade.createRoom(nickname);
Expand All @@ -63,7 +63,7 @@ class 방_참여 {
// given
String nickname = "나는참가자";
String uuid = "uuid4";
MemberResponse expectedMemberResponse = new MemberResponse(13L, nickname, false);
MemberResponse expectedMemberResponse = new MemberResponse(14L, nickname, false);

// when
RoomJoinResponse actual = roomFacade.joinRoom(nickname, uuid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import ddangkong.exception.BadRequestException;
import ddangkong.facade.BaseServiceTest;
import ddangkong.facade.balance.vote.dto.ContentTotalBalanceVoteResponse;
import ddangkong.facade.balance.vote.dto.GiveUpVoteMemberResponse;
import ddangkong.facade.balance.vote.dto.OptionTotalBalanceVoteResponse;
import ddangkong.facade.room.balance.roomvote.dto.ContentRoomBalanceVoteResponse;
import ddangkong.facade.room.balance.roomvote.dto.OptionRoomBalanceVoteResponse;
Expand Down Expand Up @@ -147,7 +148,8 @@ class 투표_결과_조회 {
3, 75),
new OptionRoomBalanceVoteResponse(2L,
"반민초",
List.of("rapper lee"), 1, 25)
List.of("rapper lee"), 1, 25),
new GiveUpVoteMemberResponse(List.of("giveUpMember"), 1)
),
new ContentTotalBalanceVoteResponse(
new OptionTotalBalanceVoteResponse(1L, "민초", 50),
Expand Down
3 changes: 2 additions & 1 deletion backend/src/test/resources/init-test.sql
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ VALUES ('mohamedeu al katan', 1, true),
('pomae', 3, false),
('ready player', 4, true),
('finish player', 5, true),
('master', 6, true);
('master', 6, true),
('giveUpMember', 1, false);

INSERT INTO room_content (room_id, balance_content_id, round, round_ended_at)
VALUES (1, 2, 1, '2024-07-18 19:50:32.000'),
Expand Down
Loading