From 73548a0916e39d231196406cf5000995a502bbbe Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Wed, 15 Nov 2023 23:34:39 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=EC=B0=B8=EC=97=AC=EC=A4=91?= =?UTF-8?q?=EC=9D=B8=20=EB=B0=A9=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../room/RoomCertificationService.java | 9 ++++++++ .../application/room/RoomSearchService.java | 22 +++++++++++++++++- .../application/room/mapper/RoomMapper.java | 23 +++++++++++++++++++ .../moabam/api/dto/room/MyRoomResponse.java | 20 ++++++++++++++++ .../moabam/api/dto/room/MyRoomsResponse.java | 12 ++++++++++ .../api/presentation/RoomController.java | 7 ++++++ 6 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/moabam/api/dto/room/MyRoomResponse.java create mode 100644 src/main/java/com/moabam/api/dto/room/MyRoomsResponse.java diff --git a/src/main/java/com/moabam/api/application/room/RoomCertificationService.java b/src/main/java/com/moabam/api/application/room/RoomCertificationService.java index c85cc1bd..13998473 100644 --- a/src/main/java/com/moabam/api/application/room/RoomCertificationService.java +++ b/src/main/java/com/moabam/api/application/room/RoomCertificationService.java @@ -112,6 +112,15 @@ public void certifyRoom(Long memberId, Long roomId, List multipar } } + public boolean existsMemberCertification(Long memberId, Long roomId, LocalDate date) { + return dailyMemberCertificationRepository.existsByMemberIdAndRoomIdAndCreatedAtBetween(memberId, roomId, + date.atStartOfDay(), date.atTime(LocalTime.MAX)); + } + + public boolean existsRoomCertification(Long roomId, LocalDate date) { + return dailyRoomCertificationRepository.existsByRoomIdAndCertifiedAt(roomId, date); + } + private void validateCertifyTime(LocalDateTime now, int certifyTime) { LocalTime targetTime = LocalTime.of(certifyTime, 0); LocalDateTime minusTenMinutes = LocalDateTime.of(now.toLocalDate(), targetTime).minusMinutes(10); diff --git a/src/main/java/com/moabam/api/application/room/RoomSearchService.java b/src/main/java/com/moabam/api/application/room/RoomSearchService.java index 7b063005..fd25b035 100644 --- a/src/main/java/com/moabam/api/application/room/RoomSearchService.java +++ b/src/main/java/com/moabam/api/application/room/RoomSearchService.java @@ -26,6 +26,8 @@ import com.moabam.api.domain.room.repository.ParticipantSearchRepository; import com.moabam.api.domain.room.repository.RoutineSearchRepository; import com.moabam.api.dto.room.CertificationImageResponse; +import com.moabam.api.dto.room.MyRoomResponse; +import com.moabam.api.dto.room.MyRoomsResponse; import com.moabam.api.dto.room.RoomDetailsResponse; import com.moabam.api.dto.room.RoutineResponse; import com.moabam.api.dto.room.TodayCertificateRankResponse; @@ -42,6 +44,7 @@ public class RoomSearchService { private final ParticipantSearchRepository participantSearchRepository; private final RoutineSearchRepository routineSearchRepository; private final MemberService memberService; + private final RoomCertificationService roomCertificationService; public RoomDetailsResponse getRoomDetails(Long memberId, Long roomId) { LocalDate today = LocalDate.now(); @@ -63,6 +66,23 @@ public RoomDetailsResponse getRoomDetails(Long memberId, Long roomId) { todayCertificateRankResponses, completePercentage); } + public MyRoomsResponse getMyRooms(Long memberId) { + LocalDate today = LocalDate.now(); + List myRoomResponses = new ArrayList<>(); + List participants = participantSearchRepository.findParticipantsByMemberId(memberId); + + for (Participant participant : participants) { + Room room = participant.getRoom(); + boolean isMemberCertified = roomCertificationService.existsMemberCertification(memberId, room.getId(), + today); + boolean isRoomCertified = roomCertificationService.existsRoomCertification(room.getId(), today); + + myRoomResponses.add(RoomMapper.toMyRoomResponse(room, isMemberCertified, isRoomCertified)); + } + + return RoomMapper.toMyRoomsResponse(myRoomResponses); + } + private List getRoutineResponses(Long roomId) { List roomRoutines = routineSearchRepository.findAllByRoomId(roomId); @@ -74,7 +94,7 @@ private List getTodayCertificateRankResponses(Long List responses = new ArrayList<>(); List certifications = certificationsSearchRepository.findCertifications(roomId, today); - List participants = participantSearchRepository.findParticipants(roomId); + List participants = participantSearchRepository.findParticipantsByRoomId(roomId); List members = memberService.getRoomMembers(participants.stream() .map(Participant::getMemberId) .toList()); diff --git a/src/main/java/com/moabam/api/application/room/mapper/RoomMapper.java b/src/main/java/com/moabam/api/application/room/mapper/RoomMapper.java index 5b005f0e..d304bbc1 100644 --- a/src/main/java/com/moabam/api/application/room/mapper/RoomMapper.java +++ b/src/main/java/com/moabam/api/application/room/mapper/RoomMapper.java @@ -5,6 +5,8 @@ import com.moabam.api.domain.room.Room; import com.moabam.api.dto.room.CreateRoomRequest; +import com.moabam.api.dto.room.MyRoomResponse; +import com.moabam.api.dto.room.MyRoomsResponse; import com.moabam.api.dto.room.RoomDetailsResponse; import com.moabam.api.dto.room.RoutineResponse; import com.moabam.api.dto.room.TodayCertificateRankResponse; @@ -45,4 +47,25 @@ public static RoomDetailsResponse toRoomDetailsResponse(Room room, String manage .todayCertificateRank(todayCertificateRankResponses) .build(); } + + public static MyRoomResponse toMyRoomResponse(Room room, boolean isMemberCertifiedToday, + boolean isRoomCertifiedToday) { + return MyRoomResponse.builder() + .roomId(room.getId()) + .title(room.getTitle()) + .roomType(room.getRoomType()) + .certifyTime(room.getCertifyTime()) + .currentUserCount(room.getCurrentUserCount()) + .maxUserCount(room.getMaxUserCount()) + .obtainedBugs(room.getLevel()) + .isMemberCertifiedToday(isMemberCertifiedToday) + .isRoomCertifiedToday(isRoomCertifiedToday) + .build(); + } + + public static MyRoomsResponse toMyRoomsResponse(List myRoomResponses) { + return MyRoomsResponse.builder() + .participatingRooms(myRoomResponses) + .build(); + } } diff --git a/src/main/java/com/moabam/api/dto/room/MyRoomResponse.java b/src/main/java/com/moabam/api/dto/room/MyRoomResponse.java new file mode 100644 index 00000000..c3480d63 --- /dev/null +++ b/src/main/java/com/moabam/api/dto/room/MyRoomResponse.java @@ -0,0 +1,20 @@ +package com.moabam.api.dto.room; + +import com.moabam.api.domain.room.RoomType; + +import lombok.Builder; + +@Builder +public record MyRoomResponse( + Long roomId, + String title, + RoomType roomType, + int certifyTime, + int currentUserCount, + int maxUserCount, + int obtainedBugs, + boolean isMemberCertifiedToday, + boolean isRoomCertifiedToday +) { + +} diff --git a/src/main/java/com/moabam/api/dto/room/MyRoomsResponse.java b/src/main/java/com/moabam/api/dto/room/MyRoomsResponse.java new file mode 100644 index 00000000..8f4a8d14 --- /dev/null +++ b/src/main/java/com/moabam/api/dto/room/MyRoomsResponse.java @@ -0,0 +1,12 @@ +package com.moabam.api.dto.room; + +import java.util.List; + +import lombok.Builder; + +@Builder +public record MyRoomsResponse( + List participatingRooms +) { + +} diff --git a/src/main/java/com/moabam/api/presentation/RoomController.java b/src/main/java/com/moabam/api/presentation/RoomController.java index 314ac697..35db06c7 100644 --- a/src/main/java/com/moabam/api/presentation/RoomController.java +++ b/src/main/java/com/moabam/api/presentation/RoomController.java @@ -21,6 +21,7 @@ import com.moabam.api.dto.room.CreateRoomRequest; import com.moabam.api.dto.room.EnterRoomRequest; import com.moabam.api.dto.room.ModifyRoomRequest; +import com.moabam.api.dto.room.MyRoomsResponse; import com.moabam.api.dto.room.RoomDetailsResponse; import com.moabam.global.auth.annotation.CurrentMember; import com.moabam.global.auth.model.AuthorizationMember; @@ -98,4 +99,10 @@ public void deportParticipant(@CurrentMember AuthorizationMember authorizationMe roomService.deportParticipant(authorizationMember.id(), roomId, memberId); } + + @GetMapping("/my-join") + @ResponseStatus(HttpStatus.OK) + public MyRoomsResponse getMyRooms(@CurrentMember AuthorizationMember authorizationMember) { + return roomSearchService.getMyRooms(authorizationMember.id()); + } } From 41383630b26ae281e8118c27b26e13aa39e952d0 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Wed, 15 Nov 2023 23:35:06 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=EA=B4=80=EB=A0=A8=20Repository=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DailyMemberCertificationRepository.java | 4 ++++ .../DailyRoomCertificationRepository.java | 3 +++ .../repository/ParticipantSearchRepository.java | 13 ++++++++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/moabam/api/domain/room/repository/DailyMemberCertificationRepository.java b/src/main/java/com/moabam/api/domain/room/repository/DailyMemberCertificationRepository.java index 2d3f7fa2..19f61f00 100644 --- a/src/main/java/com/moabam/api/domain/room/repository/DailyMemberCertificationRepository.java +++ b/src/main/java/com/moabam/api/domain/room/repository/DailyMemberCertificationRepository.java @@ -1,9 +1,13 @@ package com.moabam.api.domain.room.repository; +import java.time.LocalDateTime; + import org.springframework.data.jpa.repository.JpaRepository; import com.moabam.api.domain.room.DailyMemberCertification; public interface DailyMemberCertificationRepository extends JpaRepository { + boolean existsByMemberIdAndRoomIdAndCreatedAtBetween(Long memberId, Long roomId, LocalDateTime startTime, + LocalDateTime endTime); } diff --git a/src/main/java/com/moabam/api/domain/room/repository/DailyRoomCertificationRepository.java b/src/main/java/com/moabam/api/domain/room/repository/DailyRoomCertificationRepository.java index 16097e8d..47194085 100644 --- a/src/main/java/com/moabam/api/domain/room/repository/DailyRoomCertificationRepository.java +++ b/src/main/java/com/moabam/api/domain/room/repository/DailyRoomCertificationRepository.java @@ -1,9 +1,12 @@ package com.moabam.api.domain.room.repository; +import java.time.LocalDate; + import org.springframework.data.jpa.repository.JpaRepository; import com.moabam.api.domain.room.DailyRoomCertification; public interface DailyRoomCertificationRepository extends JpaRepository { + boolean existsByRoomIdAndCertifiedAt(Long roomId, LocalDate date); } diff --git a/src/main/java/com/moabam/api/domain/room/repository/ParticipantSearchRepository.java b/src/main/java/com/moabam/api/domain/room/repository/ParticipantSearchRepository.java index a00f7ea4..9febf65b 100644 --- a/src/main/java/com/moabam/api/domain/room/repository/ParticipantSearchRepository.java +++ b/src/main/java/com/moabam/api/domain/room/repository/ParticipantSearchRepository.java @@ -34,7 +34,7 @@ public Optional findOne(Long memberId, Long roomId) { ); } - public List findParticipants(Long roomId) { + public List findParticipantsByRoomId(Long roomId) { return jpaQueryFactory .selectFrom(participant) .where( @@ -44,6 +44,17 @@ public List findParticipants(Long roomId) { .fetch(); } + public List findParticipantsByMemberId(Long memberId) { + return jpaQueryFactory + .selectFrom(participant) + .join(participant.room, room).fetchJoin() + .where( + participant.memberId.eq(memberId), + participant.deletedAt.isNull() + ) + .fetch(); + } + public List findOtherParticipantsInRoom(Long memberId, Long roomId) { return jpaQueryFactory .selectFrom(participant) From 97e1ecafea88a3d3146f67c70206b6c6e636f4e3 Mon Sep 17 00:00:00 2001 From: ymkim97 Date: Wed, 15 Nov 2023 23:35:25 +0900 Subject: [PATCH 3/3] =?UTF-8?q?test:=20=EC=B0=B8=EC=97=AC=EC=A4=91?= =?UTF-8?q?=EC=9D=B8=20=EB=B0=A9=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../room/RoomSearchServiceTest.java | 90 +++++++++++++++++++ .../api/presentation/RoomControllerTest.java | 27 ++++++ .../moabam/support/fixture/RoomFixture.java | 17 ++++ 3 files changed, 134 insertions(+) create mode 100644 src/test/java/com/moabam/api/application/room/RoomSearchServiceTest.java diff --git a/src/test/java/com/moabam/api/application/room/RoomSearchServiceTest.java b/src/test/java/com/moabam/api/application/room/RoomSearchServiceTest.java new file mode 100644 index 00000000..de0bfffe --- /dev/null +++ b/src/test/java/com/moabam/api/application/room/RoomSearchServiceTest.java @@ -0,0 +1,90 @@ +package com.moabam.api.application.room; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.BDDMockito.*; + +import java.time.LocalDate; +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.moabam.api.application.member.MemberService; +import com.moabam.api.domain.room.Participant; +import com.moabam.api.domain.room.Room; +import com.moabam.api.domain.room.RoomType; +import com.moabam.api.domain.room.repository.CertificationsSearchRepository; +import com.moabam.api.domain.room.repository.ParticipantSearchRepository; +import com.moabam.api.domain.room.repository.RoutineSearchRepository; +import com.moabam.api.dto.room.MyRoomsResponse; +import com.moabam.support.fixture.RoomFixture; + +@ExtendWith(MockitoExtension.class) +class RoomSearchServiceTest { + + @InjectMocks + private RoomSearchService roomSearchService; + + @Mock + private CertificationsSearchRepository certificationsSearchRepository; + + @Mock + private ParticipantSearchRepository participantSearchRepository; + + @Mock + private RoutineSearchRepository routineSearchRepository; + + @Mock + private MemberService memberService; + + @Mock + private RoomCertificationService certificationService; + + @DisplayName("유저가 참여중인 방 목록 조회 성공") + @Test + void get_my_rooms_success() { + // given + LocalDate today = LocalDate.now(); + Long memberId = 1L; + Room room1 = spy(RoomFixture.room("아침 - 첫 번째 방", RoomType.MORNING, 10)); + Room room2 = spy(RoomFixture.room("아침 - 두 번째 방", RoomType.MORNING, 9)); + Room room3 = spy(RoomFixture.room("밤 - 첫 번째 방", RoomType.NIGHT, 22)); + + lenient().when(room1.getId()).thenReturn(1L); + lenient().when(room2.getId()).thenReturn(2L); + lenient().when(room3.getId()).thenReturn(3L); + + Participant participant1 = RoomFixture.participant(room1, memberId); + Participant participant2 = RoomFixture.participant(room2, memberId); + Participant participant3 = RoomFixture.participant(room3, memberId); + List participants = List.of(participant1, participant2, participant3); + + given(participantSearchRepository.findParticipantsByMemberId(memberId)).willReturn(participants); + given(certificationService.existsMemberCertification(memberId, room1.getId(), today)).willReturn(true); + given(certificationService.existsMemberCertification(memberId, room2.getId(), today)).willReturn(false); + given(certificationService.existsMemberCertification(memberId, room3.getId(), today)).willReturn(true); + + given(certificationService.existsRoomCertification(room1.getId(), today)).willReturn(true); + given(certificationService.existsRoomCertification(room2.getId(), today)).willReturn(false); + given(certificationService.existsRoomCertification(room3.getId(), today)).willReturn(false); + + // when + MyRoomsResponse myRooms = roomSearchService.getMyRooms(memberId); + + // then + assertThat(myRooms.participatingRooms()).hasSize(3); + + assertThat(myRooms.participatingRooms().get(0).isMemberCertifiedToday()).isTrue(); + assertThat(myRooms.participatingRooms().get(0).isRoomCertifiedToday()).isTrue(); + + assertThat(myRooms.participatingRooms().get(1).isMemberCertifiedToday()).isFalse(); + assertThat(myRooms.participatingRooms().get(1).isRoomCertifiedToday()).isFalse(); + + assertThat(myRooms.participatingRooms().get(2).isMemberCertifiedToday()).isTrue(); + assertThat(myRooms.participatingRooms().get(2).isRoomCertifiedToday()).isFalse(); + } +} diff --git a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java index 7ba6206a..c2f66f13 100644 --- a/src/test/java/com/moabam/api/presentation/RoomControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/RoomControllerTest.java @@ -858,4 +858,31 @@ void deport_member_success() throws Exception { assertThat(getMemberParticipant.getDeletedAt()).isNotNull(); assertThat(participantSearchRepository.findOne(member.getId(), room.getId())).isEmpty(); } + + @DisplayName("현재 참여중인 모든 방 조회 성공 - 첫번째 방은 개인과 방 모두 인증 성공") + @WithMember(id = 1L) + @Test + void get_all_my_rooms_success() throws Exception { + // given + Room room1 = RoomFixture.room("아침 - 첫 번째 방", MORNING, 10); + Room room2 = RoomFixture.room("아침 - 두 번째 방", MORNING, 8); + Room room3 = RoomFixture.room("밤 - 세 번째 방", NIGHT, 22); + + Participant participant1 = RoomFixture.participant(room1, 1L); + Participant participant2 = RoomFixture.participant(room2, 1L); + Participant participant3 = RoomFixture.participant(room3, 1L); + + DailyMemberCertification dailyMemberCertification = RoomFixture.dailyMemberCertification(1L, 1L, participant1); + DailyRoomCertification dailyRoomCertification = RoomFixture.dailyRoomCertification(1L, LocalDate.now()); + + roomRepository.saveAll(List.of(room1, room2, room3)); + participantRepository.saveAll(List.of(participant1, participant2, participant3)); + dailyMemberCertificationRepository.save(dailyMemberCertification); + dailyRoomCertificationRepository.save(dailyRoomCertification); + + // expected + mockMvc.perform(get("/rooms/my-join")) + .andExpect(status().isOk()) + .andDo(print()); + } } diff --git a/src/test/java/com/moabam/support/fixture/RoomFixture.java b/src/test/java/com/moabam/support/fixture/RoomFixture.java index 088429e2..ccdce73f 100644 --- a/src/test/java/com/moabam/support/fixture/RoomFixture.java +++ b/src/test/java/com/moabam/support/fixture/RoomFixture.java @@ -37,6 +37,23 @@ public static Room room(int certifyTime) { .build(); } + public static Room room(String title, RoomType roomType, int certifyTime) { + return Room.builder() + .title(title) + .roomType(roomType) + .certifyTime(certifyTime) + .maxUserCount(8) + .build(); + } + + public static List rooms() { + return List.of( + room("아침 - 첫 번째 방", RoomType.MORNING, 10), + room("아침 - 두 번째 방", RoomType.MORNING, 9), + room("밤 - 첫 번째 방", RoomType.NIGHT, 22) + ); + } + public static Participant participant(Room room, Long memberId) { return Participant.builder() .room(room)