diff --git a/main/src/main/java/org/sopt/makers/crew/main/entity/user/vo/UserActivityVO.java b/main/src/main/java/org/sopt/makers/crew/main/entity/user/vo/UserActivityVO.java index c2f96ab6..1d78ce5a 100644 --- a/main/src/main/java/org/sopt/makers/crew/main/entity/user/vo/UserActivityVO.java +++ b/main/src/main/java/org/sopt/makers/crew/main/entity/user/vo/UserActivityVO.java @@ -2,6 +2,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.ToString; @@ -9,6 +10,7 @@ @Getter @RequiredArgsConstructor @ToString +@EqualsAndHashCode public class UserActivityVO { @Schema(description = "파트", example = "서버") diff --git a/main/src/main/java/org/sopt/makers/crew/main/global/dto/MeetingResponseDto.java b/main/src/main/java/org/sopt/makers/crew/main/global/dto/MeetingResponseDto.java index da189093..07022937 100644 --- a/main/src/main/java/org/sopt/makers/crew/main/global/dto/MeetingResponseDto.java +++ b/main/src/main/java/org/sopt/makers/crew/main/global/dto/MeetingResponseDto.java @@ -70,7 +70,7 @@ public class MeetingResponseDto { @Schema(description = "모임장 정보", example = "") @NotNull private final MeetingCreatorDto user; - @Schema(description = "신청 수", example = "7") + @Schema(description = "신청 승인 수", example = "7") @NotNull private final int appliedCount; diff --git a/main/src/main/java/org/sopt/makers/crew/main/meeting/v2/service/MeetingV2ServiceImpl.java b/main/src/main/java/org/sopt/makers/crew/main/meeting/v2/service/MeetingV2ServiceImpl.java index 4cd9a638..ea58a499 100644 --- a/main/src/main/java/org/sopt/makers/crew/main/meeting/v2/service/MeetingV2ServiceImpl.java +++ b/main/src/main/java/org/sopt/makers/crew/main/meeting/v2/service/MeetingV2ServiceImpl.java @@ -257,7 +257,7 @@ public MeetingV2GetAllMeetingDto getMeetings(MeetingV2GetAllMeetingQueryDto quer List meetingResponseDtos = meetings.getContent().stream() .map(meeting -> MeetingResponseDto.of(meeting, meeting.getUser(), - allApplies.getAppliedCount(meeting.getId()), time.now())) + allApplies.getApprovedCount(meeting.getId()), time.now())) .toList(); PageOptionsDto pageOptionsDto = new PageOptionsDto(meetings.getPageable().getPageNumber() + 1, diff --git a/main/src/main/resources/schema.sql b/main/src/main/resources/schema.sql index 1cd8c405..534b5ae2 100644 --- a/main/src/main/resources/schema.sql +++ b/main/src/main/resources/schema.sql @@ -74,7 +74,7 @@ create table if not exists apply constraint "FK_359c8244808809db5ee96ed066e" references "user" on delete cascade, - content varchar not null, + content varchar , "appliedDate" timestamp not null, status integer default 0 not null, "createdTimestamp" timestamp default CURRENT_TIMESTAMP, diff --git a/main/src/test/java/org/sopt/makers/crew/main/meeting/v2/service/MeetingV2ServiceTest.java b/main/src/test/java/org/sopt/makers/crew/main/meeting/v2/service/MeetingV2ServiceTest.java index 69a6da93..69b7202e 100644 --- a/main/src/test/java/org/sopt/makers/crew/main/meeting/v2/service/MeetingV2ServiceTest.java +++ b/main/src/test/java/org/sopt/makers/crew/main/meeting/v2/service/MeetingV2ServiceTest.java @@ -1,5 +1,7 @@ package org.sopt.makers.crew.main.meeting.v2.service; +import static org.assertj.core.groups.Tuple.*; +import static org.sopt.makers.crew.main.entity.meeting.enums.MeetingJoinablePart.*; import static org.sopt.makers.crew.main.global.constant.CrewConst.*; import static org.sopt.makers.crew.main.global.exception.ErrorStatus.*; @@ -21,9 +23,15 @@ import org.sopt.makers.crew.main.entity.user.User; import org.sopt.makers.crew.main.entity.user.UserRepository; import org.sopt.makers.crew.main.entity.user.vo.UserActivityVO; +import org.sopt.makers.crew.main.global.dto.MeetingCreatorDto; +import org.sopt.makers.crew.main.global.dto.MeetingResponseDto; +import org.sopt.makers.crew.main.meeting.v2.dto.query.MeetingV2GetAllMeetingQueryDto; import org.sopt.makers.crew.main.meeting.v2.dto.request.MeetingV2CreateMeetingBodyDto; import org.sopt.makers.crew.main.meeting.v2.dto.response.MeetingV2CreateMeetingResponseDto; +import org.sopt.makers.crew.main.meeting.v2.dto.response.MeetingV2GetAllMeetingDto; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.jdbc.SqlGroup; @IntegratedTest public class MeetingV2ServiceTest { @@ -84,7 +92,8 @@ void normal_createMeeting_meetingId(boolean canJoinOnlyActiveGeneration) { ); // when - MeetingV2CreateMeetingResponseDto responseDto = meetingV2Service.createMeeting(meetingDto, savedUser.getId()); + MeetingV2CreateMeetingResponseDto responseDto = meetingV2Service.createMeeting(meetingDto, + savedUser.getId()); Meeting foundMeeting = meetingRepository.findByIdOrThrow(responseDto.getMeetingId()); // then @@ -102,12 +111,12 @@ void normal_createMeeting_meetingId(boolean canJoinOnlyActiveGeneration) { savedUser.getId(), // userId 필드 "알고보면 쓸데있는 개발 프로세스", // title 필드 MeetingCategory.STUDY, // category 필드 - LocalDateTime.of(2024, 10, 1, 0, 0,0), // startDate 필드 - LocalDateTime.of(2024, 10, 15, 23, 59,59), // endDate 필드 + LocalDateTime.of(2024, 10, 1, 0, 0, 0), // startDate 필드 + LocalDateTime.of(2024, 10, 15, 23, 59, 59), // endDate 필드 10, // capacity 필드 "백엔드 개발에 관심 있는 사람들을 위한 스터디입니다.", // desc 필드 "매주 온라인으로 진행되며, 발표와 토론이 포함됩니다.", // processDesc 필드 - LocalDateTime.of(2024, 10, 16, 0, 0,0), // mStartDate 필드 + LocalDateTime.of(2024, 10, 16, 0, 0, 0), // mStartDate 필드 LocalDateTime.of(2024, 12, 30, 23, 59, 59), // mEndDate 필드 "5년차 백엔드 개발자입니다.", // leaderDesc 필드 "준비물은 노트북과 열정입니다.", // note 필드 @@ -115,7 +124,7 @@ void normal_createMeeting_meetingId(boolean canJoinOnlyActiveGeneration) { canJoinOnlyActiveGeneration, // canJoinOnlyActiveGeneration 필드 ACTIVE_GENERATION, // createdGeneration 필드 canJoinOnlyActiveGeneration ? ACTIVE_GENERATION : null, // targetActiveGeneration 필드 - new MeetingJoinablePart[]{MeetingJoinablePart.SERVER, MeetingJoinablePart.IOS} // joinableParts 필드 + new MeetingJoinablePart[] {MeetingJoinablePart.SERVER, MeetingJoinablePart.IOS} // joinableParts 필드 ); Assertions.assertThat(foundMeeting.getImageURL()) @@ -265,4 +274,64 @@ void isImageFileEmpty_createMeeting_exception() { .hasMessageContaining(VALIDATION_EXCEPTION.getErrorCode()); } } + + @Nested + @SqlGroup({ + @Sql(value = "/sql/meeting-service-test-data.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD), + @Sql(value = "/sql/delete-all-data.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) + + }) + class 모임_전체_조회 { + @Test + @DisplayName("활동기수 아닌 경우를 포함하여 모임 전체 조회 시, 모임 목록을 반환한다.") + void normal_getMeetings_success() { + // given + int page = 1; + int take = 12; + MeetingV2GetAllMeetingQueryDto queryDto = new MeetingV2GetAllMeetingQueryDto(page, take); + queryDto.setIsOnlyActiveGeneration(false); + + // when + MeetingV2GetAllMeetingDto meetingDto = meetingV2Service.getMeetings(queryDto); + List meetings = meetingDto.meetings(); + List meetingCreatorDtos = meetings.stream() + .map(MeetingResponseDto::getUser) + .toList(); + + // then + Assertions.assertThat(meetings) + .extracting( + "id", "title", "category", "canJoinOnlyActiveGeneration", + "mStartDate", "mEndDate", + "capacity", "isMentorNeeded", "targetActiveGeneration", + "joinableParts", "status", "appliedCount" + ).containsExactly( + tuple(2, "스터디 구합니다 - 신청전", "스터디", false, + LocalDateTime.of(2024, 5, 29, 0, 0), + LocalDateTime.of(2024, 5, 31, 23, 59, 59), + 10, false, null, + new MeetingJoinablePart[] {PM, SERVER}, 0, 0 + ), + tuple(1, "스터디 구합니다1", "행사", true, + LocalDateTime.of(2024, 5, 29, 0, 0), + LocalDateTime.of(2024, 5, 31, 23, 59, 59), + 10, true, 35, + new MeetingJoinablePart[] {PM, SERVER}, 1, 2 + ) + + ); + + Assertions.assertThat(meetingCreatorDtos) + .extracting("id", "name", "orgId", "profileImage", "activities", "phone") + .containsExactly( + tuple(5, "모임개설자2", 1005, "profile5.jpg", + List.of(new UserActivityVO("iOS", 35), new UserActivityVO("안드로이드", 34)), + "010-6666-6666"), + tuple(1, "모임개설자", 1001, "profile1.jpg", + List.of(new UserActivityVO("서버", 33), new UserActivityVO("iOS", 32)), + "010-1234-5678") + + ); + } + } } diff --git a/main/src/test/resources/sql/meeting-service-test-data.sql b/main/src/test/resources/sql/meeting-service-test-data.sql new file mode 100644 index 00000000..77639244 --- /dev/null +++ b/main/src/test/resources/sql/meeting-service-test-data.sql @@ -0,0 +1,43 @@ +INSERT INTO "user" (id, name, "orgId", activities, "profileImage", phone) +VALUES (1, '모임개설자', 1001, + '[{"part": "서버", "generation": 33}, {"part": "iOS", "generation": 32}]', + 'profile1.jpg', '010-1234-5678'), + (2, '승인신청자', 1002, + '[{"part": "기획", "generation": 32}, {"part": "기획", "generation": 29}, {"part": "기획", "generation": 33}, {"part": "기획", "generation": 30}]', + 'profile2.jpg', '010-1111-2222'), + (3, '승인신청자', 1003, + '[{"part": "웹", "generation": 34}]', + 'profile3.jpg', '010-3333-4444'), + (4, '대기신청자', 1004, + '[{"part": "iOS", "generation": 32}, {"part": "안드로이드", "generation": 29}]', + 'profile4.jpg', '010-5555-5555'), + (5, '모임개설자2', 1005, + '[{"part": "iOS", "generation": 35}, {"part": "안드로이드", "generation": 34}]', + 'profile5.jpg', '010-6666-6666'); + +INSERT INTO meeting (id, "userId", title, category, "imageURL", "startDate", "endDate", capacity, + "desc", "processDesc", "mStartDate", "mEndDate", "leaderDesc", + note, "isMentorNeeded", "canJoinOnlyActiveGeneration", "createdGeneration", + "targetActiveGeneration", "joinableParts") +VALUES (1, 1, '스터디 구합니다1', '행사', + '[{"id": 0, "url": "https://makers-web-img.s3.ap-northeast-2.amazonaws.com/meeting/2024/05/19/79ba8312-0ebf-48a2-9a5e-b372fb8a9e64.png"}]', + '2024-04-24 00:00:00.000000', '2024-05-24 23:59:59.000000', 10, + '스터디 설명입니다.', '스터디 진행방식입니다.', + '2024-05-29 00:00:00.000000', '2024-05-31 23:59:59.000000', '스터디장 설명입니다.', + '시간지키세요.', true, true, 35, 35, '{PM,SERVER}'), + + (2, 5, '스터디 구합니다 - 신청전', '스터디', + '[{"id": 0, "url": "https://makers-web-img.s3.ap-northeast-2.amazonaws.com/meeting/2024/05/19/79ba8312-0ebf-48a2-9a5e-b372fb8a9e64.png"}]', + '2024-04-25 00:00:00.000000', '2024-05-24 23:59:59.000000', 10, + '스터디 설명입니다.', '스터디 진행방식입니다.', + '2024-05-29 00:00:00.000000', '2024-05-31 23:59:59.000000', null, + null, false, false, 34, null, '{PM,SERVER}'); + +INSERT INTO apply (type, "meetingId", "userId", "appliedDate", status) +VALUES (0, 1, 2, '2024-05-19 00:00:00.913489', 1), + (0, 1, 3, '2024-05-19 00:00:02.413489', 1), + (0, 1, 4, '2024-05-19 00:00:03.413489', 0), + (0, 2, 2, '2024-05-19 00:00:03.413489', 0), + (0, 2, 3, '2024-05-19 00:00:03.413489', 0), + (0, 2, 4, '2024-05-19 00:00:03.413489', 0); +