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(#94) group member request handling #97

Merged
merged 5 commits into from
Nov 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.heachi.admin.common.response.JsonResult;
import com.heachi.external.clients.auth.response.UserInfoResponse;
import com.heachi.housework.api.controller.group.info.request.GroupInfoRegisterRequest;
import com.heachi.housework.api.service.auth.AuthExternalService;
import com.heachi.housework.api.service.group.info.GroupInfoService;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -62,4 +63,15 @@ public JsonResult<?> joinGroupInfo(@RequestHeader(name = "Authorization") String

return JsonResult.successOf("성공적으로 그룹에 가입했습니다.");
}

// 그룹 가입 요청 처리
@PostMapping("/register")
public JsonResult<?> joinGroupRequestHandler(@RequestHeader(name = "Authorization") String authorization,
@Valid @RequestBody GroupInfoRegisterRequest request) {
// Auth 서버에서 사용자 인증
UserInfoResponse userInfo = authExternalService.userAuthenticate(authorization);
groupInfoService.joinRequestHandler(userInfo.getEmail(), request);

return JsonResult.successOf("그룹 가입 요청을 성공적으로 수행했습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.heachi.housework.api.controller.group.info.request;

import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.*;

@Getter
public class GroupInfoRegisterRequest {
private Long groupMemberId;
private Long groupId;
@NotEmpty
private GroupInfoRegisterRequestStatusEnum status;

@Builder
private GroupInfoRegisterRequest(Long groupMemberId, Long groupId, GroupInfoRegisterRequestStatusEnum status) {
this.groupMemberId = groupMemberId;
this.groupId = groupId;
this.status = status;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.heachi.housework.api.controller.group.info.request;

public enum GroupInfoRegisterRequestStatusEnum {
ACCEPT,
REFUSE
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.heachi.housework.api.service.auth.AuthExternalService;
import com.heachi.housework.api.service.housework.info.HouseworkInfoService;
import com.heachi.housework.api.service.housework.info.request.HouseworkInfoCreateServiceRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
Expand All @@ -21,7 +22,7 @@ public class HouseworkInfoController {
@PostMapping("/{groupId}")
public JsonResult<?> createHouseworkInfo(@RequestHeader(name = "Authorization") String authorization,
@PathVariable(name = "groupId") Long groupId,
@RequestBody HouseworkInfoCreateRequest request
@Valid @RequestBody HouseworkInfoCreateRequest request
) {
// Auth 서버로 요청자 인증 요청 - 해당 그룹원인지 판별하고 상태가 ACCEPT인지 확인
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import com.heachi.admin.common.exception.ExceptionMessage;
import com.heachi.admin.common.exception.group.info.GroupInfoException;
import com.heachi.admin.common.exception.group.member.GroupMemberException;
import com.heachi.housework.api.controller.group.info.request.GroupInfoRegisterRequest;
import com.heachi.housework.api.controller.group.info.request.GroupInfoRegisterRequestStatusEnum;
import com.heachi.housework.api.service.group.info.response.GroupInfoUserGroupServiceResponse;
import com.heachi.mysql.define.group.info.repository.GroupInfoRepository;
import com.heachi.mysql.define.group.info.repository.response.GroupInfoUserGroupResponse;
Expand All @@ -28,6 +31,9 @@
import java.util.Optional;
import java.util.stream.Collectors;

import static com.heachi.mysql.define.group.info.QGroupInfo.groupInfo;
import static com.heachi.mysql.define.user.QUser.user;

@Slf4j
@Service
@Transactional(readOnly = true)
Expand Down Expand Up @@ -156,4 +162,42 @@ public void joinGroupInfo(String email, String joinCode) {
}

}

@Transactional
public void joinRequestHandler(String adminEmail, GroupInfoRegisterRequest request) {
// 그룹장의 email과 GroupId로 GROUP_MEMBER 조회
GroupMember adminGroupMember = groupMemberRepository.findGroupMemberByUserEmailAndGroupInfoId(adminEmail, request.getGroupId()).orElseThrow(() -> {
log.warn(">>>> 해당 그룹의 구성원이 아닙니다. : [{}]", adminEmail);

throw new GroupMemberException(ExceptionMessage.GROUP_MEMBER_NOT_FOUND);
});

// role이 GROUP_ADMIN(그룹장)인지 확인
if (adminGroupMember.getRole() != GroupMemberRole.GROUP_ADMIN) {
log.warn(">>>> 해당 그룹의 그룹장이 아닙니다. : [role: {}]", adminGroupMember.getRole());

throw new GroupMemberException(ExceptionMessage.GROUP_MEMBER_ROLE_NOT_ADMIN);
}

// 그룹 가입 요청자 조회
GroupMember requestGroupMember = groupMemberRepository.findGroupMemberByGroupMemberIdAndGroupInfoId(request.getGroupMemberId(), request.getGroupId()).orElseThrow(() -> {
log.warn(">>>> Group Member Not Found : [{}]", request.getGroupMemberId());

throw new GroupMemberException(ExceptionMessage.GROUP_MEMBER_NOT_FOUND);
});

// 그룹 가입 요청자 상태 확인: WAITING 상태가 아닐경우 예외처리
if (requestGroupMember.getStatus() != GroupMemberStatus.WAITING) {
log.warn(">>>> Group Member's Status Is Not WAITING : [{}]", requestGroupMember.getStatus());

throw new GroupMemberException(ExceptionMessage.GROUP_MEMBER_STATUS_NOT_WAITING);
}

// status에 따른 그룹 가입 요청 핸들링
if (request.getStatus().equals(GroupInfoRegisterRequestStatusEnum.ACCEPT)) {
requestGroupMember.acceptJoin();
} else {
requestGroupMember.refuseJoin();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package com.heachi.housework.api.service.group.info;

import com.heachi.admin.common.exception.ExceptionMessage;
import com.heachi.admin.common.exception.group.info.GroupInfoException;
import com.heachi.admin.common.exception.group.member.GroupMemberException;
import com.heachi.housework.TestConfig;
import com.heachi.housework.api.controller.group.info.request.GroupInfoRegisterRequest;
import com.heachi.housework.api.controller.group.info.request.GroupInfoRegisterRequestStatusEnum;
import com.heachi.housework.api.service.group.info.response.GroupInfoUserGroupServiceResponse;
import com.heachi.admin.common.exception.user.UserException;
import com.heachi.housework.TestConfig;
Expand All @@ -21,6 +26,8 @@
import com.heachi.mysql.define.housework.todo.repository.HouseworkTodoRepository;

import com.heachi.mysql.define.user.User;
import com.heachi.mysql.define.user.constant.UserPlatformType;
import com.heachi.mysql.define.user.constant.UserRole;
import com.heachi.mysql.define.user.repository.UserRepository;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.DisplayName;
Expand Down Expand Up @@ -244,4 +251,190 @@ void joinGroupInfoAlreadyGroupMemberStatusWITHDRAW() {
assertThat(findGroupMember.getStatus()).isEqualTo(GroupMemberStatus.WAITING);
assertThat(findGroupMember.getRole()).isEqualTo(GroupMemberRole.GROUP_MEMBER);
}

@Test
@DisplayName("그룹 가입 요청자의 상태가 WAITING이 아닐 경우 예외가 발생한다.")
void joinRequestGroupMemberStatusIsNotWAITING() {
// given
// Admin
User admin = userRepository.save(generateUser());
GroupInfo groupInfo = groupInfoRepository.save(generateGroupInfo(admin));

GroupMember adminMember = GroupMember.builder()
.groupInfo(groupInfo)
.role(GroupMemberRole.GROUP_ADMIN)
.status(GroupMemberStatus.ACCEPT)
.user(admin)
.build();
groupMemberRepository.save(adminMember);

// WAITING 상태가 아닌 그룹 멤버
User requestUser = userRepository.save(User.builder()
.platformId("11")
.platformType(UserPlatformType.KAKAO)
.role(UserRole.USER)
.name("test")
.email("[email protected]")
.phoneNumber("010-1233-0000")
.profileImageUrl("https://google.com")
.pushAlarmYn(true)
.build());
GroupMember requestMember = GroupMember.builder()
.groupInfo(groupInfo)
.role(GroupMemberRole.GROUP_MEMBER)
.status(GroupMemberStatus.ACCEPT)
.user(requestUser)
.build();
GroupMember requestWaitingMember = groupMemberRepository.save(requestMember);

GroupInfoRegisterRequest request = GroupInfoRegisterRequest.builder()
.groupMemberId(requestWaitingMember.getId())
.groupId(groupInfo.getId())
.status(GroupInfoRegisterRequestStatusEnum.REFUSE)
.build();

// when & then
GroupMemberException exception = assertThrows(GroupMemberException.class, () -> groupInfoService.joinRequestHandler(admin.getEmail(), request));
assertThat(exception.getMessage()).isEqualTo(ExceptionMessage.GROUP_MEMBER_STATUS_NOT_WAITING.getText());

}

@Test
@DisplayName("해당 그룹의 그룹장이 아닐 경우 예외가 발생한다.")
void joinResponseGroupMemberRoleIsNotAdmin() {
// given
// Admin이 아닌 그룹 멤버
User notAdmin = userRepository.save(User.builder()
.platformId("11")
.platformType(UserPlatformType.KAKAO)
.role(UserRole.USER)
.name("test")
.email("[email protected]")
.phoneNumber("010-1233-0000")
.profileImageUrl("https://google.com")
.pushAlarmYn(true)
.build());
GroupInfo groupInfo = groupInfoRepository.save(generateGroupInfo(notAdmin));
groupMemberRepository.save(generateGroupMember(notAdmin, groupInfo));

// WAITING 상태의 그룹 멤버
User requestUser = userRepository.save(generateUser());
GroupMember requestMember = GroupMember.builder()
.groupInfo(groupInfo)
.role(GroupMemberRole.GROUP_MEMBER)
.status(GroupMemberStatus.WAITING)
.user(requestUser)
.build();
GroupMember requestWaitingMember = groupMemberRepository.save(requestMember);

GroupInfoRegisterRequest request = GroupInfoRegisterRequest.builder()
.groupMemberId(requestWaitingMember.getId())
.groupId(groupInfo.getId())
.status(GroupInfoRegisterRequestStatusEnum.ACCEPT)
.build();

// when & then
GroupMemberException exception = assertThrows(GroupMemberException.class, () -> groupInfoService.joinRequestHandler(notAdmin.getEmail(), request));
assertThat(exception.getMessage()).isEqualTo(ExceptionMessage.GROUP_MEMBER_ROLE_NOT_ADMIN.getText());

}

@Test
@DisplayName("status가 true일 경우 그룹 가입 요청이 승인되어 그룹 가입 요청자의 상태가 ACCEPT로 변경된다.")
void joinRequestStatusIsTrue() {
// Admin
User admin = userRepository.save(generateUser());
GroupInfo groupInfo = groupInfoRepository.save(generateGroupInfo(admin));

GroupMember adminMember = GroupMember.builder()
.groupInfo(groupInfo)
.role(GroupMemberRole.GROUP_ADMIN)
.status(GroupMemberStatus.ACCEPT)
.user(admin)
.build();
groupMemberRepository.save(adminMember);

// WAITING 상태의 그룹 멤버
User requestUser = userRepository.save(User.builder()
.platformId("11")
.platformType(UserPlatformType.KAKAO)
.role(UserRole.USER)
.name("test")
.email("[email protected]")
.phoneNumber("010-1233-0000")
.profileImageUrl("https://google.com")
.pushAlarmYn(true)
.build());
GroupMember requestMember = GroupMember.builder()
.groupInfo(groupInfo)
.role(GroupMemberRole.GROUP_MEMBER)
.status(GroupMemberStatus.WAITING)
.user(requestUser)
.build();
GroupMember requestWaitingMember = groupMemberRepository.save(requestMember);

GroupInfoRegisterRequest request = GroupInfoRegisterRequest.builder()
.groupMemberId(requestWaitingMember.getId())
.groupId(groupInfo.getId())
.status(GroupInfoRegisterRequestStatusEnum.ACCEPT)
.build();

// when
groupInfoService.joinRequestHandler(admin.getEmail(), request);


// then
GroupMember updateMember = groupMemberRepository.findById(requestWaitingMember.getId()).get();
assertThat(updateMember.getStatus()).isEqualTo(GroupMemberStatus.ACCEPT);
}

@Test
@DisplayName("status가 false일 경우 그룹 가입 요청이 거절되어 그룹 가입 요청자의 상태가 WITHDRAW로 변경된다.")
void joinRequestStatusIsFalse() {
// Admin
User admin = userRepository.save(generateUser());
GroupInfo groupInfo = groupInfoRepository.save(generateGroupInfo(admin));

GroupMember adminMember = GroupMember.builder()
.groupInfo(groupInfo)
.role(GroupMemberRole.GROUP_ADMIN)
.status(GroupMemberStatus.ACCEPT)
.user(admin)
.build();
groupMemberRepository.save(adminMember);

// WAITING 상태의 그룹 멤버
User requestUser = userRepository.save(User.builder()
.platformId("11")
.platformType(UserPlatformType.KAKAO)
.role(UserRole.USER)
.name("test")
.email("[email protected]")
.phoneNumber("010-1233-0000")
.profileImageUrl("https://google.com")
.pushAlarmYn(true)
.build());
GroupMember requestMember = GroupMember.builder()
.groupInfo(groupInfo)
.role(GroupMemberRole.GROUP_MEMBER)
.status(GroupMemberStatus.WAITING)
.user(requestUser)
.build();
GroupMember requestWaitingMember = groupMemberRepository.save(requestMember);

GroupInfoRegisterRequest request = GroupInfoRegisterRequest.builder()
.groupMemberId(requestWaitingMember.getId())
.groupId(groupInfo.getId())
.status(GroupInfoRegisterRequestStatusEnum.REFUSE)
.build();

// when
groupInfoService.joinRequestHandler(admin.getEmail(), request);


// then
GroupMember updateMember = groupMemberRepository.findById(requestWaitingMember.getId()).get();
assertThat(updateMember.getStatus()).isEqualTo(GroupMemberStatus.WITHDRAW);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,14 @@ public void rejoinGroup() {
this.role = GroupMemberRole.GROUP_MEMBER;
this.status = GroupMemberStatus.WAITING;
}

// 그룹 가입 요청을 승인받았을 경우
public void acceptJoin() {
this.status = GroupMemberStatus.ACCEPT;
}

// 그룹 가입 요청을 거절당했을 경우
public void refuseJoin() {
this.status = GroupMemberStatus.WITHDRAW;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.heachi.mysql.define.group.member.GroupMember;
import com.heachi.mysql.define.user.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.Optional;

Expand All @@ -12,4 +14,9 @@ public interface GroupMemberRepository extends JpaRepository<GroupMember, Long>,
Optional<GroupMember> findByUser(User user);

Optional<GroupMember> findByUserAndGroupInfo(User user, GroupInfo groupInfo);

Optional<GroupMember> findByUserAndGroupInfo_id(User user, Long groupId);

@Query("select gm from GROUP_MEMBER gm where gm.id = :id and gm.groupInfo.id = :groupId")
Optional<GroupMember> findByIdAndGroupInfoId(@Param("id")Long groupMemberId, @Param("groupId")Long groupId);
jusung-c marked this conversation as resolved.
Show resolved Hide resolved
}
Loading