Skip to content

Commit

Permalink
Merge branch 'dev' into feat(#93)-housework-todo
Browse files Browse the repository at this point in the history
  • Loading branch information
ghdcksgml1 authored Nov 5, 2023
2 parents 2ccd7f1 + 166833e commit f5e6673
Show file tree
Hide file tree
Showing 11 changed files with 324 additions and 2 deletions.
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);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.heachi.mysql.define.group.member.repository;

import com.heachi.mysql.define.group.member.GroupMember;
import com.heachi.mysql.define.user.User;

import java.util.List;
import java.util.Optional;
Expand All @@ -19,4 +20,10 @@ public interface GroupMemberRepositoryCustom {
// Email과 todoId를 통해 GroupMember를 조회한다.
public Optional<GroupMember> findGroupMemberByUserEmailAndTodoId(String email, Long todoId);

// 그룹 멤버의 ID와 User 정보를 이용해 그룹 멤버를 조회한다.
public Optional<GroupMember> findGroupMemberByGroupMemberIdAndGroupInfoId(Long groupMemberId, Long groupId);

// User의 email과 GroupId를 이용해 그룹 멤버를 조회한다.
public Optional<GroupMember> findGroupMemberByUserEmailAndGroupInfoId(String userEmail, Long groupId);

}
Loading

0 comments on commit f5e6673

Please sign in to comment.