From 9c086d103eab741be59268851477d00fe8ac336c Mon Sep 17 00:00:00 2001 From: Park Seyeon Date: Wed, 29 Nov 2023 18:48:22 +0900 Subject: [PATCH] Fix/#175 fix member delete error (#178) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: Base64관련 디코딩 코드 변경 -> Base64Url * refactor: 쿠폰 스케쥴 업데이트 및 config 수정 * style: 문자열 checkstyle 수정 * fix: 회원 탈퇴시 방 참여에 대한 문제 해결 * refactor: config update * test: 신고 실패에 대한 테스트 코드 변경 --- .../api/application/member/MemberService.java | 28 ++++++++++++++++++- .../api/application/report/ReportService.java | 19 +++++++------ .../api/application/room/RoomService.java | 4 +-- .../moabam/api/domain/member/BadgeType.java | 2 +- .../com/moabam/api/domain/member/Member.java | 12 ++++++-- .../repository/ParticipantRepository.java | 3 ++ .../ParticipantSearchRepository.java | 11 ++++++++ .../moabam/api/dto/member/BadgeResponse.java | 2 +- .../api/presentation/RoomController.java | 2 +- .../global/error/model/ErrorMessage.java | 1 + .../application/member/MemberServiceTest.java | 10 +++++++ .../application/report/ReportServiceTest.java | 2 +- .../api/application/room/RoomServiceTest.java | 4 +-- .../presentation/MemberControllerTest.java | 26 ++++++++--------- .../presentation/ReportControllerTest.java | 9 ++++-- 15 files changed, 98 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/moabam/api/application/member/MemberService.java b/src/main/java/com/moabam/api/application/member/MemberService.java index 295a6186..2c53f243 100644 --- a/src/main/java/com/moabam/api/application/member/MemberService.java +++ b/src/main/java/com/moabam/api/application/member/MemberService.java @@ -17,6 +17,9 @@ import com.moabam.api.domain.member.Member; import com.moabam.api.domain.member.repository.MemberRepository; import com.moabam.api.domain.member.repository.MemberSearchRepository; +import com.moabam.api.domain.room.Participant; +import com.moabam.api.domain.room.repository.ParticipantRepository; +import com.moabam.api.domain.room.repository.ParticipantSearchRepository; import com.moabam.api.dto.auth.AuthorizationTokenInfoResponse; import com.moabam.api.dto.auth.LoginResponse; import com.moabam.api.dto.member.MemberInfo; @@ -42,6 +45,8 @@ public class MemberService { private final InventoryRepository inventoryRepository; private final ItemRepository itemRepository; private final MemberSearchRepository memberSearchRepository; + private final ParticipantSearchRepository participantSearchRepository; + private final ParticipantRepository participantRepository; private final ClockHolder clockHolder; public Member findMember(Long memberId) { @@ -69,6 +74,12 @@ public Member findMemberToDelete(Long memberId) { @Transactional public void delete(Member member) { + List participants = participantRepository.findAllByMemberId(member.getId()); + + if (!participants.isEmpty()) { + throw new BadRequestException(NEED_TO_EXIT_ALL_ROOMS); + } + member.delete(clockHolder.times()); memberRepository.flush(); memberRepository.delete(member); @@ -92,14 +103,29 @@ public void modifyInfo(AuthMember authMember, ModifyMemberRequest modifyMemberRe Member member = memberSearchRepository.findMember(authMember.id()) .orElseThrow(() -> new NotFoundException(MEMBER_NOT_FOUND)); - member.changeNickName(modifyMemberRequest.nickname()); + boolean nickNameChanged = member.changeNickName(modifyMemberRequest.nickname()); member.changeIntro(modifyMemberRequest.intro()); member.changeProfileUri(newProfileUri); memberRepository.save(member); + + if (nickNameChanged) { + changeNickname(authMember.id(), modifyMemberRequest.nickname()); + } + } + + private void changeNickname(Long memberId, String changedName) { + List participants = participantSearchRepository.findAllRoomMangerByMemberId(memberId); + + for (Participant participant : participants) { + participant.getRoom().changeManagerNickname(changedName); + } } private void validateNickname(String nickname) { + if (Objects.isNull(nickname)) { + return; + } if (StringUtils.isEmpty(nickname) && memberRepository.existsByNickname(nickname)) { throw new ConflictException(NICKNAME_CONFLICT); } diff --git a/src/main/java/com/moabam/api/application/report/ReportService.java b/src/main/java/com/moabam/api/application/report/ReportService.java index f626383d..5735c63a 100644 --- a/src/main/java/com/moabam/api/application/report/ReportService.java +++ b/src/main/java/com/moabam/api/application/report/ReportService.java @@ -31,7 +31,7 @@ public class ReportService { @Transactional public void report(AuthMember authMember, ReportRequest reportRequest) { - validateNoReportSubject(reportRequest.roomId(), reportRequest.certificationId()); + validateNoReportSubject(reportRequest.reportedId()); Report report = createReport(authMember.id(), reportRequest); reportRepository.save(report); } @@ -39,21 +39,22 @@ public void report(AuthMember authMember, ReportRequest reportRequest) { private Report createReport(Long reporterId, ReportRequest reportRequest) { Member reportedMember = memberService.findMember(reportRequest.reportedId()); + Certification certification = null; if (nonNull(reportRequest.certificationId())) { - Certification certification = certificationService.findCertification(reportRequest.certificationId()); - - return ReportMapper.toReport(reporterId, reportedMember.getId(), - null, certification, reportRequest.description()); + certification = certificationService.findCertification(reportRequest.certificationId()); } - Room room = roomService.findRoom(reportRequest.roomId()); + Room room = null; + if (nonNull(reportRequest.roomId())) { + room = roomService.findRoom(reportRequest.roomId()); + } return ReportMapper.toReport(reporterId, reportedMember.getId(), - room, null, reportRequest.description()); + room, certification, reportRequest.description()); } - private void validateNoReportSubject(Long roomId, Long certificationId) { - if (isNull(roomId) && isNull(certificationId)) { + private void validateNoReportSubject(Long reportedId) { + if (isNull(reportedId)) { throw new BadRequestException(ErrorMessage.REPORT_REQUEST_ERROR); } } diff --git a/src/main/java/com/moabam/api/application/room/RoomService.java b/src/main/java/com/moabam/api/application/room/RoomService.java index 63b2490c..d14228a6 100644 --- a/src/main/java/com/moabam/api/application/room/RoomService.java +++ b/src/main/java/com/moabam/api/application/room/RoomService.java @@ -45,7 +45,7 @@ public class RoomService { private final MemberService memberService; @Transactional - public Long createRoom(Long memberId, String nickname, CreateRoomRequest createRoomRequest) { + public Long createRoom(Long memberId, CreateRoomRequest createRoomRequest) { Room room = RoomMapper.toRoomEntity(createRoomRequest); List routines = RoutineMapper.toRoutineEntities(room, createRoomRequest.routines()); Participant participant = ParticipantMapper.toParticipant(room, memberId); @@ -55,7 +55,7 @@ public Long createRoom(Long memberId, String nickname, CreateRoomRequest createR Member member = memberService.findMember(memberId); member.enterRoom(room.getRoomType()); participant.enableManager(); - room.changeManagerNickname(nickname); + room.changeManagerNickname(member.getNickname()); Room savedRoom = roomRepository.save(room); routineRepository.saveAll(routines); diff --git a/src/main/java/com/moabam/api/domain/member/BadgeType.java b/src/main/java/com/moabam/api/domain/member/BadgeType.java index 92e90edf..82a7ebd1 100644 --- a/src/main/java/com/moabam/api/domain/member/BadgeType.java +++ b/src/main/java/com/moabam/api/domain/member/BadgeType.java @@ -27,7 +27,7 @@ public enum BadgeType { public static List memberBadgeMap(Set badgeTypes) { return Arrays.stream(BadgeType.values()) .map(badgeType -> BadgeResponse.builder() - .badge(badgeType) + .badge(badgeType.korean) .unlock(badgeTypes.contains(badgeType)) .build()) .toList(); diff --git a/src/main/java/com/moabam/api/domain/member/Member.java b/src/main/java/com/moabam/api/domain/member/Member.java index 48486941..51e8d9c3 100644 --- a/src/main/java/com/moabam/api/domain/member/Member.java +++ b/src/main/java/com/moabam/api/domain/member/Member.java @@ -7,6 +7,7 @@ import static java.util.Objects.*; import java.time.LocalDateTime; +import java.util.Objects; import org.hibernate.annotations.ColumnDefault; import org.hibernate.annotations.SQLDelete; @@ -47,7 +48,7 @@ public class Member extends BaseTimeEntity { @Column(name = "social_id", nullable = false, unique = true) private String socialId; - @Column(name = "nickname", nullable = false, unique = true) + @Column(name = "nickname", unique = true) private String nickname; @Column(name = "intro", length = 30) @@ -134,10 +135,15 @@ public void increaseTotalCertifyCount() { public void delete(LocalDateTime now) { socialId = deleteSocialId(now); + nickname = null; } - public void changeNickName(String nickname) { - this.nickname = requireNonNullElse(nickname, this.nickname); + public boolean changeNickName(String nickname) { + if (Objects.isNull(nickname)) { + return false; + } + this.nickname = nickname; + return true; } public void changeIntro(String intro) { diff --git a/src/main/java/com/moabam/api/domain/room/repository/ParticipantRepository.java b/src/main/java/com/moabam/api/domain/room/repository/ParticipantRepository.java index 6d79e3df..875e6a03 100644 --- a/src/main/java/com/moabam/api/domain/room/repository/ParticipantRepository.java +++ b/src/main/java/com/moabam/api/domain/room/repository/ParticipantRepository.java @@ -1,9 +1,12 @@ package com.moabam.api.domain.room.repository; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; import com.moabam.api.domain.room.Participant; public interface ParticipantRepository extends JpaRepository { + List findAllByMemberId(Long id); } 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 761ea8c3..ed9ea08e 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 @@ -76,4 +76,15 @@ public List findAllByRoomCertifyTime(int certifyTime) { ) .fetch(); } + + public List findAllRoomMangerByMemberId(Long memberId) { + return jpaQueryFactory + .selectFrom(participant) + .join(participant.room, room).fetchJoin() + .where( + participant.memberId.eq(memberId), + participant.isManager.isTrue() + ) + .fetch(); + } } diff --git a/src/main/java/com/moabam/api/dto/member/BadgeResponse.java b/src/main/java/com/moabam/api/dto/member/BadgeResponse.java index 7e83d5d6..a00158ba 100644 --- a/src/main/java/com/moabam/api/dto/member/BadgeResponse.java +++ b/src/main/java/com/moabam/api/dto/member/BadgeResponse.java @@ -6,7 +6,7 @@ @Builder public record BadgeResponse( - BadgeType badge, + String badge, boolean unlock ) { diff --git a/src/main/java/com/moabam/api/presentation/RoomController.java b/src/main/java/com/moabam/api/presentation/RoomController.java index ce4725e3..2581e5e1 100644 --- a/src/main/java/com/moabam/api/presentation/RoomController.java +++ b/src/main/java/com/moabam/api/presentation/RoomController.java @@ -52,7 +52,7 @@ public class RoomController { @PostMapping @ResponseStatus(HttpStatus.CREATED) public Long createRoom(@Auth AuthMember authMember, @Valid @RequestBody CreateRoomRequest createRoomRequest) { - return roomService.createRoom(authMember.id(), authMember.nickname(), createRoomRequest); + return roomService.createRoom(authMember.id(), createRoomRequest); } @GetMapping diff --git a/src/main/java/com/moabam/global/error/model/ErrorMessage.java b/src/main/java/com/moabam/global/error/model/ErrorMessage.java index 907c756b..8a16d99b 100644 --- a/src/main/java/com/moabam/global/error/model/ErrorMessage.java +++ b/src/main/java/com/moabam/global/error/model/ErrorMessage.java @@ -29,6 +29,7 @@ public enum ErrorMessage { INVALID_REQUEST_URL("잘못된 URL 요청입니다."), INVALID_CERTIFY_TIME("현재 인증 시간이 아닙니다."), CERTIFICATION_NOT_FOUND("인증 정보가 없습니다."), + NEED_TO_EXIT_ALL_ROOMS("모든 방에서 나가야 회원 탈퇴가 가능합니다."), PARTICIPANT_DEPORT_ERROR("방장은 자신을 추방할 수 없습니다."), LOGIN_FAILED("로그인에 실패했습니다."), diff --git a/src/test/java/com/moabam/api/application/member/MemberServiceTest.java b/src/test/java/com/moabam/api/application/member/MemberServiceTest.java index a7959641..c4a4d6cc 100644 --- a/src/test/java/com/moabam/api/application/member/MemberServiceTest.java +++ b/src/test/java/com/moabam/api/application/member/MemberServiceTest.java @@ -24,6 +24,8 @@ import com.moabam.api.domain.member.Member; import com.moabam.api.domain.member.repository.MemberRepository; import com.moabam.api.domain.member.repository.MemberSearchRepository; +import com.moabam.api.domain.room.repository.ParticipantRepository; +import com.moabam.api.domain.room.repository.ParticipantSearchRepository; import com.moabam.api.dto.auth.AuthorizationTokenInfoResponse; import com.moabam.api.dto.auth.LoginResponse; import com.moabam.api.dto.member.MemberInfo; @@ -54,6 +56,12 @@ class MemberServiceTest { @Mock MemberSearchRepository memberSearchRepository; + @Mock + ParticipantRepository participantRepository; + + @Mock + ParticipantSearchRepository participantSearchRepository; + @Mock InventorySearchRepository inventorySearchRepository; @@ -204,6 +212,8 @@ void modify_success_test(@WithMember AuthMember authMember) { Member member = MemberFixture.member(); ModifyMemberRequest modifyMemberRequest = ModifyImageFixture.modifyMemberRequest(); given(memberSearchRepository.findMember(authMember.id())).willReturn(Optional.ofNullable(member)); + given(participantSearchRepository.findAllRoomMangerByMemberId(any())) + .willReturn(List.of()); // when memberService.modifyInfo(authMember, modifyMemberRequest, "/main"); diff --git a/src/test/java/com/moabam/api/application/report/ReportServiceTest.java b/src/test/java/com/moabam/api/application/report/ReportServiceTest.java index 25b56d96..4adc8c01 100644 --- a/src/test/java/com/moabam/api/application/report/ReportServiceTest.java +++ b/src/test/java/com/moabam/api/application/report/ReportServiceTest.java @@ -52,7 +52,7 @@ class ReportServiceTest { @Test void no_report_subject_fail(@WithMember AuthMember authMember) { // given - ReportRequest reportRequest = new ReportRequest(5L, null, null, "st"); + ReportRequest reportRequest = new ReportRequest(null, null, null, "st"); // When + Then assertThatThrownBy(() -> reportService.report(authMember, reportRequest)) diff --git a/src/test/java/com/moabam/api/application/room/RoomServiceTest.java b/src/test/java/com/moabam/api/application/room/RoomServiceTest.java index c2921883..667508f0 100644 --- a/src/test/java/com/moabam/api/application/room/RoomServiceTest.java +++ b/src/test/java/com/moabam/api/application/room/RoomServiceTest.java @@ -70,7 +70,7 @@ void create_room_no_password_success() { given(memberService.findMember(1L)).willReturn(member); // when - Long result = roomService.createRoom(1L, "닉네임", createRoomRequest); + Long result = roomService.createRoom(1L, createRoomRequest); // then verify(roomRepository).save(any(Room.class)); @@ -98,7 +98,7 @@ void create_room_with_password_success() { given(memberService.findMember(1L)).willReturn(member); // when - Long result = roomService.createRoom(1L, "닉네임", createRoomRequest); + Long result = roomService.createRoom(1L, createRoomRequest); // then verify(roomRepository).save(any(Room.class)); diff --git a/src/test/java/com/moabam/api/presentation/MemberControllerTest.java b/src/test/java/com/moabam/api/presentation/MemberControllerTest.java index 4c19555c..659bc5a8 100644 --- a/src/test/java/com/moabam/api/presentation/MemberControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/MemberControllerTest.java @@ -192,7 +192,7 @@ void delete_member_success() throws Exception { Member deletedMEmber = deletedMemberOptional.get(); assertThat(deletedMEmber.getDeletedAt()).isNotNull(); - assertThat(deletedMEmber.getNickname()).isEqualTo(nickname); + assertThat(deletedMEmber.getNickname()).isNull(); } @DisplayName("회원이 없어서 회원 삭제 실패") @@ -291,13 +291,13 @@ void search_my_info_success() throws Exception { // MockMvcResultMatchers.jsonPath("$.birds.MORNING").value(morningInven.getItem().getImage()), // MockMvcResultMatchers.jsonPath("$.birds.NIGHT").value(nightInven.getItem().getImage()), - MockMvcResultMatchers.jsonPath("$.badges[0].badge").value("MORNING_BIRTH"), + MockMvcResultMatchers.jsonPath("$.badges[0].badge").value("오목눈이 탄생"), MockMvcResultMatchers.jsonPath("$.badges[0].unlock").value(true), - MockMvcResultMatchers.jsonPath("$.badges[1].badge").value("MORNING_ADULT"), + MockMvcResultMatchers.jsonPath("$.badges[1].badge").value("어른 오목눈이"), MockMvcResultMatchers.jsonPath("$.badges[1].unlock").value(true), - MockMvcResultMatchers.jsonPath("$.badges[2].badge").value("NIGHT_BIRTH"), + MockMvcResultMatchers.jsonPath("$.badges[2].badge").value("부엉이 탄생"), MockMvcResultMatchers.jsonPath("$.badges[2].unlock").value(true), - MockMvcResultMatchers.jsonPath("$.badges[3].badge").value("NIGHT_ADULT"), + MockMvcResultMatchers.jsonPath("$.badges[3].badge").value("어른 부엉이"), MockMvcResultMatchers.jsonPath("$.badges[3].unlock").value(false), MockMvcResultMatchers.jsonPath("$.goldenBug").value(member.getBug().getGoldenBug()), MockMvcResultMatchers.jsonPath("$.morningBug").value(member.getBug().getMorningBug()), @@ -342,13 +342,13 @@ void search_my_info_with_no_badge_success() throws Exception { // MockMvcResultMatchers.jsonPath("$.birds.MORNING").value(morningInven.getItem().getImage()), // MockMvcResultMatchers.jsonPath("$.birds.NIGHT").value(nightInven.getItem().getImage()), - MockMvcResultMatchers.jsonPath("$.badges[0].badge").value("MORNING_BIRTH"), + MockMvcResultMatchers.jsonPath("$.badges[0].badge").value("오목눈이 탄생"), MockMvcResultMatchers.jsonPath("$.badges[0].unlock").value(false), - MockMvcResultMatchers.jsonPath("$.badges[1].badge").value("MORNING_ADULT"), + MockMvcResultMatchers.jsonPath("$.badges[1].badge").value("어른 오목눈이"), MockMvcResultMatchers.jsonPath("$.badges[1].unlock").value(false), - MockMvcResultMatchers.jsonPath("$.badges[2].badge").value("NIGHT_BIRTH"), + MockMvcResultMatchers.jsonPath("$.badges[2].badge").value("부엉이 탄생"), MockMvcResultMatchers.jsonPath("$.badges[2].unlock").value(false), - MockMvcResultMatchers.jsonPath("$.badges[3].badge").value("NIGHT_ADULT"), + MockMvcResultMatchers.jsonPath("$.badges[3].badge").value("어른 부엉이"), MockMvcResultMatchers.jsonPath("$.badges[3].unlock").value(false), MockMvcResultMatchers.jsonPath("$.goldenBug").value(member.getBug().getGoldenBug()), MockMvcResultMatchers.jsonPath("$.morningBug").value(member.getBug().getMorningBug()), @@ -405,13 +405,13 @@ void search_friend_info_success() throws Exception { MockMvcResultMatchers.jsonPath("$.birds.MORNING").value(morningInven.getItem().getAwakeImage()), MockMvcResultMatchers.jsonPath("$.birds.NIGHT").value(nightInven.getItem().getAwakeImage()), - MockMvcResultMatchers.jsonPath("$.badges[0].badge").value("MORNING_BIRTH"), + MockMvcResultMatchers.jsonPath("$.badges[0].badge").value("오목눈이 탄생"), MockMvcResultMatchers.jsonPath("$.badges[0].unlock").value(true), - MockMvcResultMatchers.jsonPath("$.badges[1].badge").value("MORNING_ADULT"), + MockMvcResultMatchers.jsonPath("$.badges[1].badge").value("어른 오목눈이"), MockMvcResultMatchers.jsonPath("$.badges[1].unlock").value(true), - MockMvcResultMatchers.jsonPath("$.badges[2].badge").value("NIGHT_BIRTH"), + MockMvcResultMatchers.jsonPath("$.badges[2].badge").value("부엉이 탄생"), MockMvcResultMatchers.jsonPath("$.badges[2].unlock").value(true), - MockMvcResultMatchers.jsonPath("$.badges[3].badge").value("NIGHT_ADULT"), + MockMvcResultMatchers.jsonPath("$.badges[3].badge").value("어른 부엉이"), MockMvcResultMatchers.jsonPath("$.badges[3].unlock").value(true) ).andDo(print()); } diff --git a/src/test/java/com/moabam/api/presentation/ReportControllerTest.java b/src/test/java/com/moabam/api/presentation/ReportControllerTest.java index fd724c07..006eb10a 100644 --- a/src/test/java/com/moabam/api/presentation/ReportControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/ReportControllerTest.java @@ -105,19 +105,22 @@ void reports_success(boolean roomFilter, boolean certificationFilter) throws Exc .andExpect(status().is2xxSuccessful()); } - @DisplayName("방과 인증 값 둘 다 들어오지 않는다면 테스트 실패") + @DisplayName("사용자 신고 성공") @WithMember @Test void reports_failBy_subject_null() throws Exception { // given - ReportRequest reportRequest = ReportFixture.reportRequest(123L, null, null); + Member member = MemberFixture.member("2", "ji"); + memberRepository.save(member); + + ReportRequest reportRequest = ReportFixture.reportRequest(member.getId(), null, null); String request = objectMapper.writeValueAsString(reportRequest); // expected mockMvc.perform(post("/reports") .contentType(MediaType.APPLICATION_JSON) .content(request)) - .andExpect(status().isBadRequest()); + .andExpect(status().is2xxSuccessful()); } @DisplayName("회원 조회 실패로 신고 실패")