From 359613bb376122ba8af9e95e2fc7cc6f789810c0 Mon Sep 17 00:00:00 2001 From: "khb6997@gmail.com" Date: Wed, 29 May 2024 21:39:33 +0900 Subject: [PATCH 1/7] =?UTF-8?q?=EA=B3=B5=EC=9A=A9=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=9F=AC=EB=A6=AC=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- group-service/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/group-service/build.gradle b/group-service/build.gradle index b2b189f..3ddf0a5 100644 --- a/group-service/build.gradle +++ b/group-service/build.gradle @@ -18,6 +18,7 @@ configurations { } repositories { + mavenLocal() mavenCentral() } @@ -30,6 +31,8 @@ dependencies { annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + implementation 'me.kong:common-library:0.0.1-SNAPSHOT' } tasks.named('test') { From c04c7fc8fe57de674731d2658b70efa471f7ec20 Mon Sep 17 00:00:00 2001 From: "khb6997@gmail.com" Date: Wed, 29 May 2024 22:21:58 +0900 Subject: [PATCH 2/7] =?UTF-8?q?=EA=B7=B8=EB=A3=B9=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C,=20=EA=B7=B8=EB=A3=B9=20=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC=20API=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/GroupController.java | 30 +++++++++++++++++-- .../dto/request/GroupJoinProcessDto.java | 19 ++++++++++++ .../request/enums/GroupJoinProcessAction.java | 6 ++++ .../enums/JoinRequestSearchCondition.java | 7 +++++ 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 group-service/src/main/java/me/kong/groupservice/dto/request/GroupJoinProcessDto.java create mode 100644 group-service/src/main/java/me/kong/groupservice/dto/request/enums/GroupJoinProcessAction.java create mode 100644 group-service/src/main/java/me/kong/groupservice/dto/request/enums/JoinRequestSearchCondition.java diff --git a/group-service/src/main/java/me/kong/groupservice/controller/GroupController.java b/group-service/src/main/java/me/kong/groupservice/controller/GroupController.java index ae05df7..b95be0a 100644 --- a/group-service/src/main/java/me/kong/groupservice/controller/GroupController.java +++ b/group-service/src/main/java/me/kong/groupservice/controller/GroupController.java @@ -5,16 +5,24 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import me.kong.groupservice.domain.entity.group.Group; +import me.kong.groupservice.dto.request.GroupJoinProcessDto; import me.kong.groupservice.dto.request.GroupJoinRequestDto; +import me.kong.groupservice.dto.request.enums.JoinRequestSearchCondition; import me.kong.groupservice.dto.request.SaveGroupRequestDto; +import me.kong.groupservice.dto.response.GroupJoinResponseDto; import me.kong.groupservice.dto.response.GroupResponseDto; +import me.kong.groupservice.mapper.GroupJoinRequestMapper; import me.kong.groupservice.mapper.GroupMapper; +import me.kong.groupservice.service.GroupJoinRequestService; import me.kong.groupservice.service.GroupService; -import me.kong.groupservice.service.ProfileService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.List; + +import static me.kong.commonlibrary.constant.HttpStatusResponseEntity.RESPONSE_OK; + @Slf4j @RestController @RequestMapping("/api/groups") @@ -22,8 +30,9 @@ public class GroupController { private final GroupService groupService; - + private final GroupJoinRequestService joinRequestService; private final GroupMapper groupMapper; + private final GroupJoinRequestMapper requestMapper; @PostMapping public ResponseEntity addGroup(@RequestBody @Valid SaveGroupRequestDto dto) { @@ -39,4 +48,21 @@ public ResponseEntity joinGroup(@PathVariable Long groupId, @Request return ResponseEntity.status(HttpStatus.OK).build(); } + @GetMapping("{groupId}/requests") + public ResponseEntity> getGroupRequests( + @PathVariable Long groupId, + @RequestParam(name = "status", defaultValue = "PENDING") JoinRequestSearchCondition condition) { + List requests = requestMapper.toDtoList(joinRequestService.getGroupJoinRequestsByGroupIdAndCondition(groupId, condition)); + + return new ResponseEntity<>(requests, HttpStatus.OK); + } + + @PatchMapping("{groupId}/requests/{requestId}") + public ResponseEntity handleGroupJoinRequest(@PathVariable Long groupId, + @PathVariable Long requestId, + @RequestBody GroupJoinProcessDto processDto) { + joinRequestService.processGroupJoinRequest(requestId, processDto); + + return RESPONSE_OK; + } } diff --git a/group-service/src/main/java/me/kong/groupservice/dto/request/GroupJoinProcessDto.java b/group-service/src/main/java/me/kong/groupservice/dto/request/GroupJoinProcessDto.java new file mode 100644 index 0000000..e21ef85 --- /dev/null +++ b/group-service/src/main/java/me/kong/groupservice/dto/request/GroupJoinProcessDto.java @@ -0,0 +1,19 @@ +package me.kong.groupservice.dto.request; + + +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import me.kong.groupservice.dto.request.enums.GroupJoinProcessAction; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class GroupJoinProcessDto { + + @NotNull + private GroupJoinProcessAction action; +} diff --git a/group-service/src/main/java/me/kong/groupservice/dto/request/enums/GroupJoinProcessAction.java b/group-service/src/main/java/me/kong/groupservice/dto/request/enums/GroupJoinProcessAction.java new file mode 100644 index 0000000..2c0543b --- /dev/null +++ b/group-service/src/main/java/me/kong/groupservice/dto/request/enums/GroupJoinProcessAction.java @@ -0,0 +1,6 @@ +package me.kong.groupservice.dto.request.enums; + +public enum GroupJoinProcessAction { + APPROVE, + REJECT; +} diff --git a/group-service/src/main/java/me/kong/groupservice/dto/request/enums/JoinRequestSearchCondition.java b/group-service/src/main/java/me/kong/groupservice/dto/request/enums/JoinRequestSearchCondition.java new file mode 100644 index 0000000..0c6b2cc --- /dev/null +++ b/group-service/src/main/java/me/kong/groupservice/dto/request/enums/JoinRequestSearchCondition.java @@ -0,0 +1,7 @@ +package me.kong.groupservice.dto.request.enums; + +public enum JoinRequestSearchCondition { + PENDING, + PROCESSED, + ALL; +} From 8f60f0d90eee31bae6ea4dc541916bd6fb0d0389 Mon Sep 17 00:00:00 2001 From: "khb6997@gmail.com" Date: Wed, 29 May 2024 22:22:37 +0900 Subject: [PATCH 3/7] =?UTF-8?q?=EB=B0=98=ED=99=98=20DTO,=20Mapper=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 --- .../dto/response/GroupJoinResponseDto.java | 15 +++++++++++++++ .../mapper/GroupJoinRequestMapper.java | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 group-service/src/main/java/me/kong/groupservice/dto/response/GroupJoinResponseDto.java diff --git a/group-service/src/main/java/me/kong/groupservice/dto/response/GroupJoinResponseDto.java b/group-service/src/main/java/me/kong/groupservice/dto/response/GroupJoinResponseDto.java new file mode 100644 index 0000000..ab16fb4 --- /dev/null +++ b/group-service/src/main/java/me/kong/groupservice/dto/response/GroupJoinResponseDto.java @@ -0,0 +1,15 @@ +package me.kong.groupservice.dto.response; + +import lombok.Builder; +import lombok.Getter; +import me.kong.groupservice.domain.entity.GroupJoinRequest.JoinResponse; + +@Getter +@Builder +public class GroupJoinResponseDto { + private Long requestId; + private String nickname; + private String requestInfo; + private JoinResponse status; + private Long userId; +} diff --git a/group-service/src/main/java/me/kong/groupservice/mapper/GroupJoinRequestMapper.java b/group-service/src/main/java/me/kong/groupservice/mapper/GroupJoinRequestMapper.java index b41f8c3..86c7677 100644 --- a/group-service/src/main/java/me/kong/groupservice/mapper/GroupJoinRequestMapper.java +++ b/group-service/src/main/java/me/kong/groupservice/mapper/GroupJoinRequestMapper.java @@ -7,9 +7,12 @@ import me.kong.groupservice.domain.entity.State; import me.kong.groupservice.domain.entity.group.Group; import me.kong.groupservice.dto.request.GroupJoinRequestDto; +import me.kong.groupservice.dto.response.GroupJoinResponseDto; import me.kong.groupservice.dto.response.GroupResponseDto; import org.springframework.stereotype.Component; +import java.util.List; + @Component @RequiredArgsConstructor public class GroupJoinRequestMapper { @@ -25,4 +28,20 @@ public GroupJoinRequest toEntity(GroupJoinRequestDto dto, Group group) { .group(group) .build(); } + + public GroupJoinResponseDto toDto(GroupJoinRequest request) { + return GroupJoinResponseDto.builder() + .requestId(request.getId()) + .nickname(request.getNickname()) + .requestInfo(request.getRequestInfo()) + .status(request.getResponse()) + .userId(request.getUserId()) + .build(); + } + + public List toDtoList(List requests) { + return requests.stream() + .map(this::toDto) + .toList(); + } } From 278d05308b56c54427b657f1a7948c9d1d734980 Mon Sep 17 00:00:00 2001 From: "khb6997@gmail.com" Date: Wed, 29 May 2024 22:34:14 +0900 Subject: [PATCH 4/7] =?UTF-8?q?repository,=20=EC=9D=91=EB=8B=B5=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EB=B3=80=EA=B2=BD=20=EB=A9=94=EC=86=8C=EB=93=9C=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/GroupJoinRequest/GroupJoinRequest.java | 8 ++++++++ .../repository/GroupJoinRequestRepository.java | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/group-service/src/main/java/me/kong/groupservice/domain/entity/GroupJoinRequest/GroupJoinRequest.java b/group-service/src/main/java/me/kong/groupservice/domain/entity/GroupJoinRequest/GroupJoinRequest.java index a3e6284..0cd32c7 100644 --- a/group-service/src/main/java/me/kong/groupservice/domain/entity/GroupJoinRequest/GroupJoinRequest.java +++ b/group-service/src/main/java/me/kong/groupservice/domain/entity/GroupJoinRequest/GroupJoinRequest.java @@ -41,4 +41,12 @@ public GroupJoinRequest(Long id, String requestInfo, String nickname, JoinRespon this.userId = userId; this.group = group; } + + public void approveJoinRequest() { + response = JoinResponse.APPROVED; + } + + public void rejectJoinRequest() { + response = JoinResponse.REJECTED; + } } diff --git a/group-service/src/main/java/me/kong/groupservice/domain/repository/GroupJoinRequestRepository.java b/group-service/src/main/java/me/kong/groupservice/domain/repository/GroupJoinRequestRepository.java index dcb7ff7..21eefc9 100644 --- a/group-service/src/main/java/me/kong/groupservice/domain/repository/GroupJoinRequestRepository.java +++ b/group-service/src/main/java/me/kong/groupservice/domain/repository/GroupJoinRequestRepository.java @@ -17,4 +17,18 @@ default boolean pendingRequestExists(Long userId, Long groupId) { } Optional findByResponseAndUserIdAndGroupId(JoinResponse response, Long userId, Long groupId); + + List findAllByGroupId(Long groupId); + + default List findPendingGroupJoinRequests(Long groupId) { + return findAllByGroupIdAndResponse(groupId, JoinResponse.PENDING); + } + + default List findProcessedGroupJoinRequests(Long groupId) { + return findAllByGroupIdAndResponseNot(groupId, JoinResponse.PENDING); + } + + List findAllByGroupIdAndResponse(Long groupId, JoinResponse response); + + List findAllByGroupIdAndResponseNot(Long groupId, JoinResponse response); } From c7947da7ce44a1a4e44351c5d50643d2c1d0ed18 Mon Sep 17 00:00:00 2001 From: "khb6997@gmail.com" Date: Wed, 29 May 2024 22:35:19 +0900 Subject: [PATCH 5/7] =?UTF-8?q?=EA=B7=B8=EB=A3=B9=20=EA=B6=8C=ED=95=9C=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/kong/groupservice/service/ProfileService.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/group-service/src/main/java/me/kong/groupservice/service/ProfileService.java b/group-service/src/main/java/me/kong/groupservice/service/ProfileService.java index 025cef9..32eaa70 100644 --- a/group-service/src/main/java/me/kong/groupservice/service/ProfileService.java +++ b/group-service/src/main/java/me/kong/groupservice/service/ProfileService.java @@ -1,6 +1,7 @@ package me.kong.groupservice.service; import lombok.RequiredArgsConstructor; +import me.kong.commonlibrary.exception.auth.UnAuthorizedException; import me.kong.groupservice.common.JwtReader; import me.kong.groupservice.common.exception.NoLoggedInProfileException; import me.kong.groupservice.domain.entity.State; @@ -11,7 +12,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; @Service @@ -40,4 +40,14 @@ public Profile getLoggedInProfile(Long groupId) { return profileRepository.findByUserIdAndGroupId(userId, groupId).orElseThrow(NoLoggedInProfileException::new); } + + @Transactional(readOnly = true) + public void checkLoggedInProfileIsGroupManager(Long groupId) { + Profile profile = getLoggedInProfile(groupId); + + if (profile.getGroupRole() != GroupRole.MANAGER) { + throw new UnAuthorizedException("권한이 없습니다. groupId : " + + groupId + ", profileId : " + profile.getId() + " , userId : " + profile.getUserId()); + } + } } From ee0d2d95df8fb6921d10830823ef3da79144a8cb Mon Sep 17 00:00:00 2001 From: "khb6997@gmail.com" Date: Wed, 29 May 2024 22:36:02 +0900 Subject: [PATCH 6/7] =?UTF-8?q?=EA=B7=B8=EB=A3=B9=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C,=20=EC=B2=98=EB=A6=AC=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/GroupJoinRequestService.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/group-service/src/main/java/me/kong/groupservice/service/GroupJoinRequestService.java b/group-service/src/main/java/me/kong/groupservice/service/GroupJoinRequestService.java index 4e7a934..a373d15 100644 --- a/group-service/src/main/java/me/kong/groupservice/service/GroupJoinRequestService.java +++ b/group-service/src/main/java/me/kong/groupservice/service/GroupJoinRequestService.java @@ -2,13 +2,22 @@ import lombok.RequiredArgsConstructor; import me.kong.groupservice.common.JwtReader; +import me.kong.groupservice.common.exception.DuplicateElementException; +import me.kong.groupservice.domain.entity.GroupJoinRequest.GroupJoinRequest; +import me.kong.groupservice.domain.entity.GroupJoinRequest.JoinResponse; import me.kong.groupservice.domain.entity.group.Group; +import me.kong.groupservice.domain.entity.profile.GroupRole; import me.kong.groupservice.domain.repository.GroupJoinRequestRepository; +import me.kong.groupservice.dto.request.GroupJoinProcessDto; import me.kong.groupservice.dto.request.GroupJoinRequestDto; +import me.kong.groupservice.dto.request.enums.JoinRequestSearchCondition; import me.kong.groupservice.mapper.GroupJoinRequestMapper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; +import java.util.NoSuchElementException; + @Service @RequiredArgsConstructor public class GroupJoinRequestService { @@ -16,6 +25,14 @@ public class GroupJoinRequestService { private final JwtReader jwtReader; private final GroupJoinRequestRepository joinRequestRepository; private final GroupJoinRequestMapper joinRequestMapper; + private final GroupJoinRequestRepository groupJoinRequestRepository; + private final ProfileService profileService; + + @Transactional(readOnly = true) + public GroupJoinRequest getGroupJoinRequestByRequestId(Long requestId) { + return joinRequestRepository.findById(requestId) + .orElseThrow(() -> new NoSuchElementException("해당하는 가입 요청이 없습니다. id : " + requestId)); + } @Transactional(readOnly = true) public boolean pendingRequestExists(Long groupId) { @@ -26,4 +43,51 @@ public boolean pendingRequestExists(Long groupId) { public void createNewGroupJoinRequest(GroupJoinRequestDto dto, Group group) { joinRequestRepository.save(joinRequestMapper.toEntity(dto, group)); } + + @Transactional(readOnly = true) + public List getGroupJoinRequestsByGroupIdAndCondition(Long groupId, JoinRequestSearchCondition condition) { + List requests; + + profileService.checkLoggedInProfileIsGroupManager(groupId); + + switch (condition) { + case PENDING -> { + requests = groupJoinRequestRepository.findPendingGroupJoinRequests(groupId); + } + case PROCESSED -> { + requests = groupJoinRequestRepository.findProcessedGroupJoinRequests(groupId); + } + case ALL -> { + requests = groupJoinRequestRepository.findAllByGroupId(groupId); + } + default -> { + throw new IllegalArgumentException("지원하지 않는 그룹 가입 검색 조건. status : " + condition); + } + } + return requests; + } + + @Transactional + public void processGroupJoinRequest(Long requestId, GroupJoinProcessDto dto) { + GroupJoinRequest joinRequest = getGroupJoinRequestByRequestId(requestId); + + if (joinRequest.getResponse() != JoinResponse.PENDING) { + throw new DuplicateElementException("이미 처리된 가입 요청입니다. 요청 id : " + requestId); + } + + profileService.checkLoggedInProfileIsGroupManager(joinRequest.getGroup().getId()); + + switch (dto.getAction()) { + case APPROVE -> { + joinRequest.approveJoinRequest(); + profileService.createNewProfile(joinRequest.getNickname(), GroupRole.MEMBER, joinRequest.getGroup()); + } + case REJECT -> { + joinRequest.rejectJoinRequest(); + } + default -> { + throw new IllegalArgumentException("지원하지 않는 처리 요청. action : " + dto.getAction()); + } + } + } } From 8150a0bf440623fe82b38ee619a837cfd7bef426 Mon Sep 17 00:00:00 2001 From: "khb6997@gmail.com" Date: Wed, 29 May 2024 22:36:16 +0900 Subject: [PATCH 7/7] =?UTF-8?q?=EB=8B=A8=EC=9C=84=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=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 --- .../GroupManagementServiceTest.java | 6 +- .../service/GroupJoinRequestServiceTest.java | 123 +++++++++++++++++- .../service/ProfileServiceTest.java | 20 +++ .../GroupJoinRequestValidationTest.java | 28 +++- 4 files changed, 171 insertions(+), 6 deletions(-) diff --git a/group-service/src/test/java/me/kong/groupservice/integration/GroupManagementServiceTest.java b/group-service/src/test/java/me/kong/groupservice/integration/GroupManagementServiceTest.java index 85cd615..093c06d 100644 --- a/group-service/src/test/java/me/kong/groupservice/integration/GroupManagementServiceTest.java +++ b/group-service/src/test/java/me/kong/groupservice/integration/GroupManagementServiceTest.java @@ -8,13 +8,12 @@ import me.kong.groupservice.domain.repository.GroupRepository; import me.kong.groupservice.domain.repository.ProfileRepository; import me.kong.groupservice.dto.request.SaveGroupRequestDto; +import me.kong.groupservice.service.GroupJoinRequestService; import me.kong.groupservice.service.GroupService; import me.kong.groupservice.service.ProfileService; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.mockito.Mock; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @@ -29,6 +28,9 @@ public class GroupManagementServiceTest { @Autowired private GroupService groupService; + @Autowired + private GroupJoinRequestService joinRequestService; + @MockBean private ProfileService profileService; diff --git a/group-service/src/test/java/me/kong/groupservice/service/GroupJoinRequestServiceTest.java b/group-service/src/test/java/me/kong/groupservice/service/GroupJoinRequestServiceTest.java index d30d357..9de0909 100644 --- a/group-service/src/test/java/me/kong/groupservice/service/GroupJoinRequestServiceTest.java +++ b/group-service/src/test/java/me/kong/groupservice/service/GroupJoinRequestServiceTest.java @@ -1,21 +1,27 @@ package me.kong.groupservice.service; import me.kong.groupservice.common.JwtReader; +import me.kong.groupservice.common.exception.DuplicateElementException; import me.kong.groupservice.domain.entity.GroupJoinRequest.GroupJoinRequest; +import me.kong.groupservice.domain.entity.GroupJoinRequest.JoinResponse; import me.kong.groupservice.domain.entity.group.Group; +import me.kong.groupservice.domain.entity.profile.GroupRole; import me.kong.groupservice.domain.repository.GroupJoinRequestRepository; +import me.kong.groupservice.dto.request.GroupJoinProcessDto; import me.kong.groupservice.dto.request.GroupJoinRequestDto; +import me.kong.groupservice.dto.request.enums.GroupJoinProcessAction; +import me.kong.groupservice.dto.request.enums.JoinRequestSearchCondition; import me.kong.groupservice.mapper.GroupJoinRequestMapper; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import java.util.Optional; + import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @@ -27,6 +33,9 @@ class GroupJoinRequestServiceTest { @InjectMocks GroupJoinRequestService groupJoinRequestService; + @Mock + ProfileService profileService; + @Mock GroupJoinRequestRepository groupJoinRequestRepository; @@ -40,6 +49,9 @@ class GroupJoinRequestServiceTest { GroupJoinRequest request; GroupJoinRequestDto dto; Group group; + Long groupId; + JoinRequestSearchCondition condition; + GroupJoinProcessDto processDto; @BeforeEach void init() { @@ -49,6 +61,7 @@ void init() { .requestInfo("sample") .nickname("testuser") .build(); + groupId = 1L; } @Test @@ -76,4 +89,110 @@ void failedByDatabaseProblem() { assertThrows(RuntimeException.class, () -> groupJoinRequestService.createNewGroupJoinRequest(dto, group)); } + @Test + @DisplayName("searchCondition이 ALL이라면 해당 그룹의 모든 그룹 가입 요청을 조회한다") + void successToFindAllGroupJoinRequests() { + //given + JoinRequestSearchCondition condition = JoinRequestSearchCondition.ALL; + + //when + groupJoinRequestService.getGroupJoinRequestsByGroupIdAndCondition(groupId, condition); + + //then + verify(groupJoinRequestRepository, times(1)).findAllByGroupId(groupId); + } + + @Test + @DisplayName("searchCondition이 PENDING이라면 해당 그룹의 대기중인 그룹 가입 요청을 조회한다") + void successToFindPendingGroupJOinRequests() { + //given + condition = JoinRequestSearchCondition.PENDING; + + //when + groupJoinRequestService.getGroupJoinRequestsByGroupIdAndCondition(groupId, condition); + + //then + verify(groupJoinRequestRepository, times(1)) + .findPendingGroupJoinRequests(groupId); + } + + @Test + @DisplayName("searchCondition이 PROCESSED라면 처리된 그룹 가입 요청을 조회한다") + void successToFindProcessedGroupJoinRequests() { + //given + condition = JoinRequestSearchCondition.PROCESSED; + + //when + groupJoinRequestService.getGroupJoinRequestsByGroupIdAndCondition(groupId, condition); + + //then + verify(groupJoinRequestRepository, times(1)) + .findProcessedGroupJoinRequests(groupId); + } + + @Test + @DisplayName("가입 승인 시, 우 가입 요청 상태가 승인으로 변경되고 새로운 프로필을 생성한다") + void successToApproveGroupJoinRequest() { + //given + Long requestId = 1L; + processDto = getProcessDto(GroupJoinProcessAction.APPROVE); + request = getJoinRequest(JoinResponse.PENDING); + when(groupJoinRequestRepository.findById(requestId)).thenReturn(Optional.of(request)); + doNothing().when(profileService).checkLoggedInProfileIsGroupManager(anyLong()); + + // when + groupJoinRequestService.processGroupJoinRequest(requestId, processDto); + + // then + assertEquals(JoinResponse.APPROVED, request.getResponse()); + verify(profileService, times(1)).createNewProfile(request.getNickname(), GroupRole.MEMBER, request.getGroup()); + } + + @Test + @DisplayName("가입 거절 시, 가입 요청 상태가 거절로 변경된다") + void successToRejectGroupJoinRequest() { + //given + Long requestId = 1L; + processDto = getProcessDto(GroupJoinProcessAction.REJECT); + request = getJoinRequest(JoinResponse.PENDING); + when(groupJoinRequestRepository.findById(requestId)).thenReturn(Optional.of(request)); + doNothing().when(profileService).checkLoggedInProfileIsGroupManager(anyLong()); + + //when + groupJoinRequestService.processGroupJoinRequest(requestId, processDto); + + //then + assertEquals(JoinResponse.REJECTED, request.getResponse()); + } + + + @Test + @DisplayName("가입 요청이 이미 처리되었다면 예외가 발생한다") + void testProcessGroupJoinRequest_AlreadyProcessed() { + // given + Long requestId = 1L; + processDto = getProcessDto(GroupJoinProcessAction.APPROVE); + request = getJoinRequest(JoinResponse.APPROVED); + when(groupJoinRequestRepository.findById(requestId)).thenReturn(Optional.of(request)); + + // then + assertThrows(DuplicateElementException.class, () -> { + groupJoinRequestService.processGroupJoinRequest(requestId, processDto); + }); + } + + + + private GroupJoinProcessDto getProcessDto(GroupJoinProcessAction action) { + return GroupJoinProcessDto.builder() + .action(action) + .build(); + } + + private GroupJoinRequest getJoinRequest(JoinResponse response) { + return GroupJoinRequest.builder() + .response(response) + .group(group) + .build(); + } } \ No newline at end of file diff --git a/group-service/src/test/java/me/kong/groupservice/service/ProfileServiceTest.java b/group-service/src/test/java/me/kong/groupservice/service/ProfileServiceTest.java index 3308daf..d5011f4 100644 --- a/group-service/src/test/java/me/kong/groupservice/service/ProfileServiceTest.java +++ b/group-service/src/test/java/me/kong/groupservice/service/ProfileServiceTest.java @@ -1,6 +1,8 @@ package me.kong.groupservice.service; +import me.kong.commonlibrary.exception.auth.UnAuthorizedException; import me.kong.groupservice.common.JwtReader; +import me.kong.groupservice.common.exception.NoLoggedInProfileException; import me.kong.groupservice.domain.entity.group.Group; import me.kong.groupservice.domain.entity.profile.GroupRole; import me.kong.groupservice.domain.entity.profile.Profile; @@ -13,6 +15,8 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import java.util.Optional; + import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @@ -64,4 +68,20 @@ void failToCreateNewProfileByDatabaseProblem() { //then assertThrows(RuntimeException.class, () -> profileService.createNewProfile(nickname, groupRole, group)); } + + @Test + @DisplayName("그룹 매니저가 아닐 경우 예외가 발생한다") + void unAuthorizeOccurred() { + //given + Long userId = 1L; + Long groupId = 1L; + Profile profile = Profile.builder() + .groupRole(GroupRole.MEMBER) + .build(); + when(jwtReader.getUserId()).thenReturn(userId); + when(profileRepository.findByUserIdAndGroupId(userId, groupId)).thenReturn(Optional.of(profile)); + + //then + assertThrows(UnAuthorizedException.class, () -> profileService.checkLoggedInProfileIsGroupManager(groupId)); + } } \ No newline at end of file diff --git a/group-service/src/test/java/me/kong/groupservice/validation/GroupJoinRequestValidationTest.java b/group-service/src/test/java/me/kong/groupservice/validation/GroupJoinRequestValidationTest.java index 96ccc78..9545c2e 100644 --- a/group-service/src/test/java/me/kong/groupservice/validation/GroupJoinRequestValidationTest.java +++ b/group-service/src/test/java/me/kong/groupservice/validation/GroupJoinRequestValidationTest.java @@ -4,9 +4,9 @@ import jakarta.validation.Validation; import jakarta.validation.Validator; import jakarta.validation.ValidatorFactory; -import me.kong.groupservice.domain.entity.GroupJoinRequest.GroupJoinRequest; +import me.kong.groupservice.dto.request.GroupJoinProcessDto; import me.kong.groupservice.dto.request.GroupJoinRequestDto; -import me.kong.groupservice.dto.request.SaveGroupRequestDto; +import me.kong.groupservice.dto.request.enums.GroupJoinProcessAction; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -51,4 +51,28 @@ void failedByEmptyNickname() { assertEquals("nickname", violation.getPropertyPath().toString()); assertEquals("비어 있을 수 없습니다", violation.getMessage()); } + + @Test + @DisplayName("가입 요청 처리의 action이 존재한다면 검증에 성공한다") + void successToProcessGroupJoinRequest() { + GroupJoinProcessDto dto = GroupJoinProcessDto.builder() + .action(GroupJoinProcessAction.APPROVE) + .build(); + + Set> violations = validator.validate(dto); + assertThat(violations).isEmpty(); + } + + @Test + @DisplayName("가입 요청 처리의 action이 비어있다면 검증에 실패한다") + void failedByEmptyAction() { + GroupJoinProcessDto dto = GroupJoinProcessDto.builder() + .action(null) + .build(); + + Set> violations = validator.validate(dto); + ConstraintViolation violation = violations.iterator().next(); + assertEquals("action", violation.getPropertyPath().toString()); + assertEquals("널이어서는 안됩니다", violation.getMessage()); + } }