From 7f5b20465516d42cda8b9bc860ee9af735d3d639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Wed, 24 Jan 2024 22:00:00 +0900 Subject: [PATCH 01/17] =?UTF-8?q?feat:=20session=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=ED=95=84=EB=93=9C=20=EC=88=98=EC=A0=95=20=EB=B0=8F?= =?UTF-8?q?=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/session/entity/Session.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/umc/networkingService/domain/session/entity/Session.java b/src/main/java/com/umc/networkingService/domain/session/entity/Session.java index a21fd320..5bbe3c59 100644 --- a/src/main/java/com/umc/networkingService/domain/session/entity/Session.java +++ b/src/main/java/com/umc/networkingService/domain/session/entity/Session.java @@ -3,9 +3,7 @@ import com.umc.networkingService.domain.member.entity.Member; import com.umc.networkingService.global.common.base.BaseEntity; import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.SQLRestriction; import org.hibernate.annotations.UuidGenerator; @@ -15,25 +13,22 @@ @Getter @Entity +@Builder +@AllArgsConstructor @NoArgsConstructor(access= AccessLevel.PROTECTED) @SQLRestriction("deleted_at is null") @DynamicInsert public class Session extends BaseEntity { @Id @UuidGenerator - @Column(name = "session_id") private UUID id; - @ManyToOne(fetch = FetchType.LAZY) + @OneToOne(fetch = FetchType.LAZY) private Member member; - @Column(nullable = false) - private LocalDateTime startTime; - - @Column(nullable = false) - private LocalDateTime endTime; - - @Column(columnDefinition = "boolean default true") - private boolean isConnected; + private LocalDateTime lastActiveTime; + public void updateLastActiveTime(LocalDateTime lastActiveTime) { + this.lastActiveTime = lastActiveTime; + } } From 721d6a3dd4a643fa90a5b161bd898b268ec928a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Wed, 24 Jan 2024 22:15:35 +0900 Subject: [PATCH 02/17] =?UTF-8?q?refactor:=20=EC=86=8C=EC=85=9C=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20API=20=EA=B4=80=EB=A0=A8=20Swagge?= =?UTF-8?q?r=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/controller/AuthController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/umc/networkingService/domain/member/controller/AuthController.java b/src/main/java/com/umc/networkingService/domain/member/controller/AuthController.java index 3afb80d5..5147929f 100644 --- a/src/main/java/com/umc/networkingService/domain/member/controller/AuthController.java +++ b/src/main/java/com/umc/networkingService/domain/member/controller/AuthController.java @@ -26,10 +26,10 @@ public class AuthController { private final AuthService authService; - @Operation(summary = "소셜 로그인", description = "네이버, 카카오, 구글, 애플 로그인") + @Operation(summary = "소셜 로그인 API", description = "네이버, 카카오, 구글 로그인을 수행하는 API입니다.") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "로그인 성공"), - @ApiResponse(responseCode = "AUTH007", description = "외부 소셜 서버와의 통신 에러" , content = + @ApiResponse(responseCode = "AUTH007", description = "외부 소셜 서버와의 통신 에러 시 발생" , content = @Content(schema = @Schema(implementation = BaseResponse.class))) }) @PostMapping("/login") From d1374bc7e42813e44590eb997ac87d6686f37d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Wed, 24 Jan 2024 22:59:08 +0900 Subject: [PATCH 03/17] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../friend/controller/FriendController.java | 42 +++++++++++++++++++ .../friend/dto/response/FriendIdResponse.java | 12 ++++++ .../domain/friend/mapper/FriendMapper.java | 16 +++++++ .../domain/friend/service/FriendService.java | 4 ++ .../friend/service/FriendServiceImpl.java | 28 +++++++++++++ .../global/common/exception/ErrorCode.java | 4 ++ 6 files changed, 106 insertions(+) create mode 100644 src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java create mode 100644 src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendIdResponse.java create mode 100644 src/main/java/com/umc/networkingService/domain/friend/mapper/FriendMapper.java diff --git a/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java b/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java new file mode 100644 index 00000000..0bd7b5e1 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java @@ -0,0 +1,42 @@ +package com.umc.networkingService.domain.friend.controller; + +import com.umc.networkingService.config.security.auth.CurrentMember; +import com.umc.networkingService.domain.friend.dto.response.FriendIdResponse; +import com.umc.networkingService.domain.friend.service.FriendService; +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.global.common.base.BaseResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.UUID; + +@Tag(name = "친구 API", description = "친구 관련 API") +@RestController +@RequiredArgsConstructor +@RequestMapping("/friends") +public class FriendController { + + private final FriendService friendService; + + @Operation(summary = "친구 추가 API", description = "네이버, 카카오, 구글, 애플 로그인") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공"), + @ApiResponse(responseCode = "MEMBER001", description = "존재하지 않는 멤버를 친구 추가한 경우 발생"), + @ApiResponse(responseCode = "FRIEND001", description = "이미 친구 관계일 경우 발생") + }) + @Parameter(name = "memberId", in = ParameterIn.PATH, required = true, description = "친구 추가할 멤버 id입니다.") + @PostMapping("/{memberId}") + public BaseResponse createNewFriend(@CurrentMember Member member, + @PathVariable UUID memberId) { + return BaseResponse.onSuccess(friendService.createNewFriend(member, memberId)); + } +} diff --git a/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendIdResponse.java b/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendIdResponse.java new file mode 100644 index 00000000..efcecbd7 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendIdResponse.java @@ -0,0 +1,12 @@ +package com.umc.networkingService.domain.friend.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.UUID; + +@Getter +@AllArgsConstructor +public class FriendIdResponse { + private UUID friendId; +} diff --git a/src/main/java/com/umc/networkingService/domain/friend/mapper/FriendMapper.java b/src/main/java/com/umc/networkingService/domain/friend/mapper/FriendMapper.java new file mode 100644 index 00000000..6c83529d --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/friend/mapper/FriendMapper.java @@ -0,0 +1,16 @@ +package com.umc.networkingService.domain.friend.mapper; + +import com.umc.networkingService.domain.friend.entity.Friend; +import com.umc.networkingService.domain.member.entity.Member; +import org.springframework.stereotype.Component; + +@Component +public class FriendMapper { + + public Friend toFriend(Member sender, Member receiver) { + return Friend.builder() + .sender(sender) + .receiver(receiver) + .build(); + } +} diff --git a/src/main/java/com/umc/networkingService/domain/friend/service/FriendService.java b/src/main/java/com/umc/networkingService/domain/friend/service/FriendService.java index 37634c6e..f9fb5d3f 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/service/FriendService.java +++ b/src/main/java/com/umc/networkingService/domain/friend/service/FriendService.java @@ -1,7 +1,11 @@ package com.umc.networkingService.domain.friend.service; +import com.umc.networkingService.domain.friend.dto.response.FriendIdResponse; import com.umc.networkingService.domain.member.entity.Member; +import java.util.UUID; + public interface FriendService { + FriendIdResponse createNewFriend(Member member, UUID memberId); boolean checkFriend(Member sender, Member receiver); } diff --git a/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java b/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java index a880bb87..1e0b9655 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java +++ b/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java @@ -1,16 +1,44 @@ package com.umc.networkingService.domain.friend.service; +import com.umc.networkingService.domain.friend.dto.response.FriendIdResponse; +import com.umc.networkingService.domain.friend.entity.Friend; +import com.umc.networkingService.domain.friend.mapper.FriendMapper; import com.umc.networkingService.domain.friend.repository.FriendRepository; import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.member.service.MemberService; +import com.umc.networkingService.global.common.exception.ErrorCode; +import com.umc.networkingService.global.common.exception.RestApiException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.UUID; + @Service @RequiredArgsConstructor public class FriendServiceImpl implements FriendService { private final FriendRepository friendRepository; + private final FriendMapper friendMapper; + + private final MemberService memberService; + + // 친구 추가 함수 + @Override + public FriendIdResponse createNewFriend(Member member, UUID memberId) { + Member loginMember = memberService.loadEntity(member.getId()); + + Member friendMember = memberService.loadEntity(memberId); + + // 이미 존재하는 경우 예외 처리 + if (friendRepository.existsBySenderAndReceiver(loginMember, friendMember)) + throw new RestApiException(ErrorCode.ALREADY_FRIEND_RELATION); + + Friend friend = friendMapper.toFriend(loginMember, friendMember); + + return new FriendIdResponse(friendRepository.save(friend).getId()); + } + // 친구 여부 확인 함수 @Override public boolean checkFriend(Member sender, Member receiver) { return friendRepository.existsBySenderAndReceiver(sender, receiver); diff --git a/src/main/java/com/umc/networkingService/global/common/exception/ErrorCode.java b/src/main/java/com/umc/networkingService/global/common/exception/ErrorCode.java index 1db297d3..c7b65172 100644 --- a/src/main/java/com/umc/networkingService/global/common/exception/ErrorCode.java +++ b/src/main/java/com/umc/networkingService/global/common/exception/ErrorCode.java @@ -30,6 +30,10 @@ public enum ErrorCode { UNAUTHENTICATED_GITHUB(HttpStatus.BAD_REQUEST, "MEMBER005", "깃허브 연동이 완료되지 않은 사용자입니다."), INVALID_MEMBER_KEYWORD(HttpStatus.BAD_REQUEST, "MEMBER006", "검색어 양식[닉네임/이름]에 맞추어 작성해주세요. ex) 벡스/김준석"), + // Friend + ALREADY_FRIEND_RELATION(HttpStatus.BAD_REQUEST, "FRIEND001", "이미 친구 관계인 사용자입니다."), + NOT_FRIEND_RELATION(HttpStatus.CONFLICT, "FRIEND002", "친구 관계가 아닌 사용자입니다."), + // SemesterPart EMPTY_SEMESTER_PART(HttpStatus.BAD_REQUEST, "PART006", "존재하지 않는 기수의 파트입니다."), From 11e92e5849f1c94c066ea85991b28550060ad0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Wed, 24 Jan 2024 22:59:19 +0900 Subject: [PATCH 04/17] =?UTF-8?q?refactor:=20=EB=B3=80=EC=88=98=EB=AA=85?= =?UTF-8?q?=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/service/AuthServiceImpl.java | 38 ++++++------ .../member/service/MemberServiceImpl.java | 58 +++++++++---------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/umc/networkingService/domain/member/service/AuthServiceImpl.java b/src/main/java/com/umc/networkingService/domain/member/service/AuthServiceImpl.java index cbaf19f1..5cbad406 100644 --- a/src/main/java/com/umc/networkingService/domain/member/service/AuthServiceImpl.java +++ b/src/main/java/com/umc/networkingService/domain/member/service/AuthServiceImpl.java @@ -70,67 +70,67 @@ public MemberLoginResponse socialLogin(String accessToken, SocialType socialType // 회원가입을 수행하는 함수 @Override @Transactional - public MemberIdResponse signUp(Member loginMember, MemberSignUpRequest request) { + public MemberIdResponse signUp(Member member, MemberSignUpRequest request) { - Member member = loadEntity(loginMember.getId()); + Member loginMember = loadEntity(member.getId()); // 소속 대학교 탐색 University university = universityService.findUniversityByName(request.getUniversityName()); // 멤버 직책 저장 - memberPositionService.saveMemberPositionInfos(member, request.getCampusPositions(), request.getCenterPositions()); + memberPositionService.saveMemberPositionInfos(loginMember, request.getCampusPositions(), request.getCenterPositions()); // 기수별 파트 저장 - semesterPartService.saveSemesterPartInfos(member, request.getSemesterParts()); + semesterPartService.saveSemesterPartInfos(loginMember, request.getSemesterParts()); // 이외의 기본 정보 저장 - member.setMemberInfo(request.getName(), request.getNickname(), + loginMember.setMemberInfo(request.getName(), request.getNickname(), university, branchUniversityService.findBranchByUniversity(university)); - return new MemberIdResponse(memberService.saveEntity(member).getId()); + return new MemberIdResponse(memberService.saveEntity(loginMember).getId()); } // 새로운 액세스 토큰 발급 함수 @Override @Transactional - public MemberGenerateTokenResponse generateNewAccessToken(String refreshToken, Member loginMember) { + public MemberGenerateTokenResponse generateNewAccessToken(String refreshToken, Member member) { - Member member = loadEntity(loginMember.getId()); + Member loginMember = loadEntity(member.getId()); - RefreshToken savedRefreshToken = refreshTokenService.findByMemberId(member.getId()) + RefreshToken savedRefreshToken = refreshTokenService.findByMemberId(loginMember.getId()) .orElseThrow(() -> new RestApiException(ErrorCode.EXPIRED_MEMBER_JWT)); // 디비에 저장된 refreshToken과 동일하지 않다면 유효하지 않음 if (!refreshToken.equals(savedRefreshToken.getRefreshToken())) throw new RestApiException(ErrorCode.INVALID_REFRESH_TOKEN); - return new MemberGenerateTokenResponse(jwtTokenProvider.generateAccessToken(member.getId())); + return new MemberGenerateTokenResponse(jwtTokenProvider.generateAccessToken(loginMember.getId())); } // 로그아웃 함수 @Override @Transactional - public MemberIdResponse logout(Member loginMember) { - Member member = loadEntity(loginMember.getId()); + public MemberIdResponse logout(Member member) { + Member loginMember = loadEntity(member.getId()); - deleteRefreshToken(member); - return new MemberIdResponse(member.getId()); + deleteRefreshToken(loginMember); + return new MemberIdResponse(loginMember.getId()); } // 회원 탈퇴 함수 @Override @Transactional - public MemberIdResponse withdrawal(Member loginMember) { + public MemberIdResponse withdrawal(Member member) { // 멤버 soft delete - Member member = loadEntity(loginMember.getId()); + Member loginMember = loadEntity(member.getId()); // refreshToken 삭제 - deleteRefreshToken(member); + deleteRefreshToken(loginMember); // 멤버 soft delete - member.delete(); + loginMember.delete(); - return new MemberIdResponse(member.getId()); + return new MemberIdResponse(loginMember.getId()); } private MemberLoginResponse loginByApple(final String accessToken){ diff --git a/src/main/java/com/umc/networkingService/domain/member/service/MemberServiceImpl.java b/src/main/java/com/umc/networkingService/domain/member/service/MemberServiceImpl.java index 10fed2c1..8883d521 100644 --- a/src/main/java/com/umc/networkingService/domain/member/service/MemberServiceImpl.java +++ b/src/main/java/com/umc/networkingService/domain/member/service/MemberServiceImpl.java @@ -45,20 +45,20 @@ public class MemberServiceImpl implements MemberService{ // 나의 프로필 업데이트 함수 @Override @Transactional - public MemberIdResponse updateMyProfile(Member loginMember, MultipartFile profileImage, MemberUpdateMyProfileRequest request) { + public MemberIdResponse updateMyProfile(Member member, MultipartFile profileImage, MemberUpdateMyProfileRequest request) { - Member member = loadEntity(loginMember.getId()); + Member loginMember = loadEntity(member.getId()); String profileUrl = null; // 프로필 이미지 s3 저장 if (profileImage != null) - profileUrl = s3FileComponent.uploadFile("member", profileImage); + profileUrl = s3FileComponent.uploadFile("Member", profileImage); // 수정된 정보 저장 - member.updateMemberInfo(request, profileUrl); + loginMember.updateMemberInfo(request, profileUrl); - return new MemberIdResponse(memberRepository.save(member).getId()); + return new MemberIdResponse(memberRepository.save(loginMember).getId()); } // 프로필 수정 함수(운영진용) @@ -93,18 +93,18 @@ public MemberIdResponse updateProfile(Member member, UUID memberId, MemberUpdate // 프로필 조회 함수 @Override - public MemberInquiryProfileResponse inquiryProfile(Member loginMember, UUID memberId) { + public MemberInquiryProfileResponse inquiryProfile(Member member, UUID memberId) { - Member member = loadEntity(loginMember.getId()); + Member loginMember = loadEntity(member.getId()); // 본인 프로필 조회인 경우 - if (memberId == null || member.getId().equals(memberId)) { - return memberMapper.toInquiryProfileResponse(member, MemberRelation.MINE); + if (memberId == null || loginMember.getId().equals(memberId)) { + return memberMapper.toInquiryProfileResponse(loginMember, MemberRelation.MINE); } Member inquiryMember = loadEntity(memberId); // 친구 프로필 조회인 경우 - if (friendService.checkFriend(member, inquiryMember)) { + if (friendService.checkFriend(loginMember, inquiryMember)) { return memberMapper.toInquiryProfileResponse(inquiryMember, MemberRelation.FRIEND); } @@ -114,45 +114,45 @@ public MemberInquiryProfileResponse inquiryProfile(Member loginMember, UUID memb // 포인트 관련 정보 조회 @Override - public MemberInquiryInfoWithPointResponse inquiryInfoWithPoint(Member loginMember) { + public MemberInquiryInfoWithPointResponse inquiryInfoWithPoint(Member member) { - Member member = loadEntity(loginMember.getId()); + Member loginMember = loadEntity(member.getId()); // 소속 대학교 찾기 - University university = Optional.ofNullable(member.getUniversity()) + University university = Optional.ofNullable(loginMember.getUniversity()) .orElseThrow(() -> new RestApiException(ErrorCode.EMPTY_MEMBER_UNIVERSITY)); // 본인 랭킹 구하기 - int rank = calculateMyRank(member, university); + int rank = calculateMyRank(loginMember, university); - return memberMapper.toInquiryHomeInfoResponse(member, rank); + return memberMapper.toInquiryHomeInfoResponse(loginMember, rank); } // 깃허브 인증 함수 @Override @Transactional - public MemberAuthenticateGithubResponse authenticateGithub(Member loginMember, String code) { + public MemberAuthenticateGithubResponse authenticateGithub(Member member, String code) { - Member member = loadEntity(loginMember.getId()); + Member loginMember = loadEntity(member.getId()); String gitNickname = githubMemberClient.getGithubNickname(code); if (gitNickname == null || gitNickname.isBlank()) throw new RestApiException(ErrorCode.FAILED_GITHUB_AUTHENTICATION); - member.authenticateGithub(gitNickname); + loginMember.authenticateGithub(gitNickname); - Member savedMember = memberRepository.save(member); + Member savedMember = memberRepository.save(loginMember); return new MemberAuthenticateGithubResponse(savedMember.getGitNickname()); } // 깃허브 잔디 이미지 조회 함수 @Override - public MemberInquiryGithubResponse inquiryGithubImage(Member loginMember) { - Member member = loadEntity(loginMember.getId()); + public MemberInquiryGithubResponse inquiryGithubImage(Member member) { + Member loginMember = loadEntity(member.getId()); - String gitNickName = member.getGitNickname(); + String gitNickName = loginMember.getGitNickname(); if (gitNickName == null) throw new RestApiException(ErrorCode.UNAUTHENTICATED_GITHUB); return new MemberInquiryGithubResponse("https://ghchart.rshah.org/2965FF/" + gitNickName); @@ -160,30 +160,30 @@ public MemberInquiryGithubResponse inquiryGithubImage(Member loginMember) { // 포인트 관련 멤버 정보 조회 함수 @Override - public MemberInquiryPointsResponse inquiryMemberPoints(Member loginMember) { - Member member = loadEntity(loginMember.getId()); + public MemberInquiryPointsResponse inquiryMemberPoints(Member member) { + Member loginMember = loadEntity(member.getId()); Page usedPointsPage = memberPointRepository. - findAllByMemberOrderByCreatedAtDesc(member, PageRequest.of(0, 2)); + findAllByMemberOrderByCreatedAtDesc(loginMember, PageRequest.of(0, 2)); List usedHistories = usedPointsPage.stream() .map(MemberPoint::getPointType) .map(memberMapper::toUsedHistory) .toList(); - return memberMapper.toInquiryPointsResponse(member.getRemainPoint(), usedHistories); + return memberMapper.toInquiryPointsResponse(loginMember.getRemainPoint(), usedHistories); } // 멤버 검색 함수(운영진용) @Override - public List searchMemberInfo(Member loginMember, String keyword) { - Member member = loadEntity(loginMember.getId()); + public List searchMemberInfo(Member member, String keyword) { + Member loginMember = loadEntity(member.getId()); // keyword 양식 검증 String[] nicknameAndName = validateKeyword(keyword); // 해당 유저가 본인보다 상위 운영진인 경우 검색 대상에서 제외 List searchedMembers = memberRepository.findAllByNicknameAndName(nicknameAndName[0], nicknameAndName[1]).stream() - .filter(searchedMember -> searchedMember.getRole().getPriority() > member.getRole().getPriority()) + .filter(searchedMember -> searchedMember.getRole().getPriority() > loginMember.getRole().getPriority()) .toList(); From 329b9f6ddd7c467101b7f0714a8e48a232bed14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Wed, 24 Jan 2024 23:57:24 +0900 Subject: [PATCH 05/17] =?UTF-8?q?fix:=20memberService=EC=99=80=20friendSer?= =?UTF-8?q?vice=20=EC=88=9C=ED=99=98=20=EC=B0=B8=EC=A1=B0=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 도메인 서비스인 friendShipService 생성 --- .../friend/service/FriendShipService.java | 11 +++ .../friend/service/FriendShipServiceImpl.java | 44 ++++++++++ .../member/controller/MemberController.java | 4 +- .../domain/member/service/MemberService.java | 1 - .../member/service/MemberServiceImpl.java | 23 ----- .../controller/FriendControllerTest.java | 47 ++++++++++ .../service/FriendServiceIntegrationTest.java | 9 ++ .../FriendShipServiceImplIntegrationTest.java | 87 +++++++++++++++++++ .../controller/InviteControllerTest.java | 1 - .../controller/MemberControllerTest.java | 6 +- .../service/MemberServiceIntegrationTest.java | 60 +------------ .../support/ControllerTestConfig.java | 10 +-- 12 files changed, 211 insertions(+), 92 deletions(-) create mode 100644 src/main/java/com/umc/networkingService/domain/friend/service/FriendShipService.java create mode 100644 src/main/java/com/umc/networkingService/domain/friend/service/FriendShipServiceImpl.java create mode 100644 src/test/java/com/umc/networkingService/domain/friend/controller/FriendControllerTest.java create mode 100644 src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java create mode 100644 src/test/java/com/umc/networkingService/domain/friend/service/FriendShipServiceImplIntegrationTest.java diff --git a/src/main/java/com/umc/networkingService/domain/friend/service/FriendShipService.java b/src/main/java/com/umc/networkingService/domain/friend/service/FriendShipService.java new file mode 100644 index 00000000..837e0a42 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/friend/service/FriendShipService.java @@ -0,0 +1,11 @@ +package com.umc.networkingService.domain.friend.service; + + +import com.umc.networkingService.domain.member.dto.response.MemberInquiryProfileResponse; +import com.umc.networkingService.domain.member.entity.Member; + +import java.util.UUID; + +public interface FriendShipService { + MemberInquiryProfileResponse inquiryProfile(Member member, UUID memberId); + } diff --git a/src/main/java/com/umc/networkingService/domain/friend/service/FriendShipServiceImpl.java b/src/main/java/com/umc/networkingService/domain/friend/service/FriendShipServiceImpl.java new file mode 100644 index 00000000..09b00e06 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/friend/service/FriendShipServiceImpl.java @@ -0,0 +1,44 @@ +package com.umc.networkingService.domain.friend.service; + +import com.umc.networkingService.domain.friend.repository.FriendRepository; +import com.umc.networkingService.domain.member.dto.response.MemberInquiryProfileResponse; +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.member.entity.MemberRelation; +import com.umc.networkingService.domain.member.mapper.MemberMapper; +import com.umc.networkingService.domain.member.repository.MemberRepository; +import com.umc.networkingService.domain.member.service.MemberService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class FriendShipServiceImpl implements FriendShipService{ + private final FriendService friendService; + private final MemberService memberService; + + private final MemberMapper memberMapper; + + // 프로필 조회 함수 + @Override + public MemberInquiryProfileResponse inquiryProfile(Member member, UUID memberId) { + + Member loginMember = memberService.loadEntity(member.getId()); + // 본인 프로필 조회인 경우 + if (memberId == null || loginMember.getId().equals(memberId)) { + return memberMapper.toInquiryProfileResponse(loginMember, MemberRelation.MINE); + } + + Member inquiryMember = memberService.loadEntity(memberId); + + // 친구 프로필 조회인 경우 + if (friendService.checkFriend(loginMember, inquiryMember)) { + return memberMapper.toInquiryProfileResponse(inquiryMember, MemberRelation.FRIEND); + } + + // 이외의 프로필 조회인 경우 + return memberMapper.toInquiryProfileResponse(inquiryMember, MemberRelation.OTHERS); + } + +} diff --git a/src/main/java/com/umc/networkingService/domain/member/controller/MemberController.java b/src/main/java/com/umc/networkingService/domain/member/controller/MemberController.java index c5d39dad..6ce08803 100644 --- a/src/main/java/com/umc/networkingService/domain/member/controller/MemberController.java +++ b/src/main/java/com/umc/networkingService/domain/member/controller/MemberController.java @@ -2,6 +2,7 @@ import com.umc.networkingService.config.security.auth.CurrentMember; +import com.umc.networkingService.domain.friend.service.FriendShipService; import com.umc.networkingService.domain.member.dto.request.MemberUpdateMyProfileRequest; import com.umc.networkingService.domain.member.dto.response.*; import com.umc.networkingService.domain.member.entity.Member; @@ -26,6 +27,7 @@ public class MemberController { private final MemberService memberService; + private final FriendShipService friendShipService; @Operation(summary = "나의 프로필 수정 API", description = "본인 프로필 사진, 닉네임, 이름, 상태 메시지를 수정하는 API입니다.") @ApiResponses( value = { @@ -48,7 +50,7 @@ public BaseResponse updateMyProfile(@CurrentMember Member memb @GetMapping(value = {"", "/{memberId}"}) public BaseResponse inquiryProfile(@CurrentMember Member member, @PathVariable(required = false) UUID memberId) { - return BaseResponse.onSuccess(memberService.inquiryProfile(member, memberId)); + return BaseResponse.onSuccess(friendShipService.inquiryProfile(member, memberId)); } @Operation(summary = "포인트 관련 유저 정보 조회 API", description = "닉네임, 프로필 사진, 기여도, 랭킹을 조회하는 API입니다.") diff --git a/src/main/java/com/umc/networkingService/domain/member/service/MemberService.java b/src/main/java/com/umc/networkingService/domain/member/service/MemberService.java index 380162e7..094528ca 100644 --- a/src/main/java/com/umc/networkingService/domain/member/service/MemberService.java +++ b/src/main/java/com/umc/networkingService/domain/member/service/MemberService.java @@ -13,7 +13,6 @@ public interface MemberService extends EntityLoader { MemberIdResponse updateMyProfile(Member member, MultipartFile profileImage, MemberUpdateMyProfileRequest request); MemberIdResponse updateProfile(Member member, UUID memberId, MemberUpdateProfileRequest request); - MemberInquiryProfileResponse inquiryProfile(Member member, UUID memberId); MemberAuthenticateGithubResponse authenticateGithub(Member member, String code); MemberInquiryInfoWithPointResponse inquiryInfoWithPoint(Member member); MemberInquiryGithubResponse inquiryGithubImage(Member member); diff --git a/src/main/java/com/umc/networkingService/domain/member/service/MemberServiceImpl.java b/src/main/java/com/umc/networkingService/domain/member/service/MemberServiceImpl.java index 8883d521..eb709d61 100644 --- a/src/main/java/com/umc/networkingService/domain/member/service/MemberServiceImpl.java +++ b/src/main/java/com/umc/networkingService/domain/member/service/MemberServiceImpl.java @@ -1,7 +1,6 @@ package com.umc.networkingService.domain.member.service; -import com.umc.networkingService.domain.friend.service.FriendService; import com.umc.networkingService.domain.member.client.GithubMemberClient; import com.umc.networkingService.domain.member.dto.request.MemberUpdateMyProfileRequest; import com.umc.networkingService.domain.member.dto.request.MemberUpdateProfileRequest; @@ -37,7 +36,6 @@ public class MemberServiceImpl implements MemberService{ private final SemesterPartService semesterPartService; private final MemberPositionService memberPositionService; - private final FriendService friendService; private final S3FileComponent s3FileComponent; private final GithubMemberClient githubMemberClient; @@ -91,27 +89,6 @@ public MemberIdResponse updateProfile(Member member, UUID memberId, MemberUpdate return new MemberIdResponse(memberRepository.save(updateMember).getId()); } - // 프로필 조회 함수 - @Override - public MemberInquiryProfileResponse inquiryProfile(Member member, UUID memberId) { - - Member loginMember = loadEntity(member.getId()); - // 본인 프로필 조회인 경우 - if (memberId == null || loginMember.getId().equals(memberId)) { - return memberMapper.toInquiryProfileResponse(loginMember, MemberRelation.MINE); - } - - Member inquiryMember = loadEntity(memberId); - - // 친구 프로필 조회인 경우 - if (friendService.checkFriend(loginMember, inquiryMember)) { - return memberMapper.toInquiryProfileResponse(inquiryMember, MemberRelation.FRIEND); - } - - // 이외의 프로필 조회인 경우 - return memberMapper.toInquiryProfileResponse(inquiryMember, MemberRelation.OTHERS); - } - // 포인트 관련 정보 조회 @Override public MemberInquiryInfoWithPointResponse inquiryInfoWithPoint(Member member) { diff --git a/src/test/java/com/umc/networkingService/domain/friend/controller/FriendControllerTest.java b/src/test/java/com/umc/networkingService/domain/friend/controller/FriendControllerTest.java new file mode 100644 index 00000000..a8a150f9 --- /dev/null +++ b/src/test/java/com/umc/networkingService/domain/friend/controller/FriendControllerTest.java @@ -0,0 +1,47 @@ +package com.umc.networkingService.domain.friend.controller; + +import com.umc.networkingService.domain.friend.dto.response.FriendIdResponse; +import com.umc.networkingService.domain.friend.service.FriendService; +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.global.common.enums.Role; +import com.umc.networkingService.support.ControllerTestConfig; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.mock.mockito.MockBean; + +import java.util.Optional; +import java.util.UUID; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@DisplayName("Friend 컨트롤러의") +public class FriendControllerTest extends ControllerTestConfig { + + @MockBean private FriendService friendService; + + @DisplayName("친구 추가 API 테스트") + @Test + public void createNewFriend() throws Exception { + // given + createMember("222222", Role.MEMBER); + + FriendIdResponse response = new FriendIdResponse(UUID.randomUUID()); + + given(friendService.createNewFriend(any(), any())).willReturn(response); + given(memberRepository.findById(any(UUID.class))).willReturn(Optional.of(member)); + + // when & then + mockMvc.perform(post("/friends/" + response.getFriendId()) + .header("Authorization", accessToken)) + .andDo(print()) // 응답 출력 + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("COMMON200")) + .andExpect(jsonPath("$.message").value("요청에 성공하였습니다.")) + .andExpect(jsonPath("$.result.friendId").value(response.getFriendId().toString())); + } +} diff --git a/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java new file mode 100644 index 00000000..14a9a174 --- /dev/null +++ b/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java @@ -0,0 +1,9 @@ +package com.umc.networkingService.domain.friend.service; + +import org.junit.jupiter.api.DisplayName; +import org.springframework.boot.test.context.SpringBootTest; + +@DisplayName("Friend 서비스의 ") +@SpringBootTest +public class FriendServiceIntegrationTest { +} diff --git a/src/test/java/com/umc/networkingService/domain/friend/service/FriendShipServiceImplIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/friend/service/FriendShipServiceImplIntegrationTest.java new file mode 100644 index 00000000..f781f0f2 --- /dev/null +++ b/src/test/java/com/umc/networkingService/domain/friend/service/FriendShipServiceImplIntegrationTest.java @@ -0,0 +1,87 @@ +package com.umc.networkingService.domain.friend.service; + +import com.umc.networkingService.domain.friend.entity.Friend; +import com.umc.networkingService.domain.friend.repository.FriendRepository; +import com.umc.networkingService.domain.member.dto.response.MemberInquiryProfileResponse; +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.member.entity.MemberRelation; +import com.umc.networkingService.domain.member.service.AuthService; +import com.umc.networkingService.global.common.enums.Role; +import com.umc.networkingService.support.ServiceIntegrationTestConfig; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@DisplayName("FriendShip 서비스의 ") +@SpringBootTest +public class FriendShipServiceImplIntegrationTest extends ServiceIntegrationTestConfig { + @Autowired + private FriendShipService friendShipService; + @Autowired + private AuthService authService; + + @Autowired + private FriendRepository friendRepository; + + @Test + @DisplayName("유저 프로필 조회 테스트 - 본인") + @Transactional + public void inquiryMyProfile() { + // given + authService.signUp(member, getInfoRequest()); + + // when + MemberInquiryProfileResponse response = friendShipService.inquiryProfile(member, null); + + // then + assertEquals("김준석", response.getName()); + assertEquals("인하대학교", response.getUniversityName()); + assertEquals(MemberRelation.MINE, response.getOwner()); + } + + @Test + @DisplayName("유저 프로필 조회 테스트 - 친구") + @Transactional + public void inquiryFriendProfile() { + // given + Member loginMember = createMember("222222", Role.CAMPUS_STAFF); + + authService.signUp(member, getInfoRequest()); + + friendRepository.save(Friend.builder() + .sender(loginMember) + .receiver(member) + .build()); + + // when + MemberInquiryProfileResponse response = friendShipService.inquiryProfile(loginMember, member.getId()); + + // then + assertEquals("김준석", response.getName()); + assertEquals("인하대학교", response.getUniversityName()); + assertEquals(MemberRelation.FRIEND, response.getOwner()); + } + + @Test + @DisplayName("유저 프로필 조회 테스트 - 그 외") + @Transactional + public void inquiryOthersProfile() { + // given + Member loginMember = createMember("222222", Role.CAMPUS_STAFF); + + authService.signUp(member, getInfoRequest()); + + // when + MemberInquiryProfileResponse response = friendShipService.inquiryProfile(loginMember, member.getId()); + + // then + assertEquals("김준석", response.getName()); + assertEquals("인하대학교", response.getUniversityName()); + assertEquals(MemberRelation.OTHERS, response.getOwner()); + } + +} diff --git a/src/test/java/com/umc/networkingService/domain/invite/controller/InviteControllerTest.java b/src/test/java/com/umc/networkingService/domain/invite/controller/InviteControllerTest.java index e838d2f3..7216bb57 100644 --- a/src/test/java/com/umc/networkingService/domain/invite/controller/InviteControllerTest.java +++ b/src/test/java/com/umc/networkingService/domain/invite/controller/InviteControllerTest.java @@ -34,7 +34,6 @@ public void createInviteCode() throws Exception { // given member.updateRole(Role.CAMPUS_STAFF); - InviteCreateResponse response = new InviteCreateResponse("초대 코드", Role.MEMBER); given(inviteService.createInviteCode(any(), any())).willReturn(response); diff --git a/src/test/java/com/umc/networkingService/domain/member/controller/MemberControllerTest.java b/src/test/java/com/umc/networkingService/domain/member/controller/MemberControllerTest.java index 5e05e251..9511aa08 100644 --- a/src/test/java/com/umc/networkingService/domain/member/controller/MemberControllerTest.java +++ b/src/test/java/com/umc/networkingService/domain/member/controller/MemberControllerTest.java @@ -1,6 +1,7 @@ package com.umc.networkingService.domain.member.controller; +import com.umc.networkingService.domain.friend.service.FriendShipService; import com.umc.networkingService.domain.member.dto.request.MemberUpdateMyProfileRequest; import com.umc.networkingService.domain.member.dto.response.*; import com.umc.networkingService.domain.member.entity.MemberRelation; @@ -39,6 +40,7 @@ public class MemberControllerTest extends ControllerTestConfig { @Autowired private MemberMapper memberMapper; @MockBean private MemberService memberService; + @MockBean private FriendShipService friendShipService; @DisplayName("나의 프로필 수정 API 테스트 - 프로필 이미지 없음") @Test @@ -121,7 +123,7 @@ public void inquiryMyProfileTest() throws Exception { .owner(MemberRelation.MINE) .build(); - given(memberService.inquiryProfile(any(), any())).willReturn(response); + given(friendShipService.inquiryProfile(any(), any())).willReturn(response); given(memberRepository.findById(any(UUID.class))).willReturn(Optional.of(member)); // when & then @@ -154,7 +156,7 @@ public void inquiryOthersProfileTest() throws Exception { .owner(MemberRelation.OTHERS) .build(); - given(memberService.inquiryProfile(any(), any())).willReturn(response); + given(friendShipService.inquiryProfile(any(), any())).willReturn(response); given(memberRepository.findById(any(UUID.class))).willReturn(Optional.of(member)); // when & then diff --git a/src/test/java/com/umc/networkingService/domain/member/service/MemberServiceIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/member/service/MemberServiceIntegrationTest.java index d7295583..148479d7 100644 --- a/src/test/java/com/umc/networkingService/domain/member/service/MemberServiceIntegrationTest.java +++ b/src/test/java/com/umc/networkingService/domain/member/service/MemberServiceIntegrationTest.java @@ -44,8 +44,7 @@ public class MemberServiceIntegrationTest extends ServiceIntegrationTestConfig { private MemberPositionRepository memberPositionRepository; @Autowired private MemberPointRepository memberPointRepository; - @Autowired - private FriendRepository friendRepository; + @MockBean private S3FileComponent s3FileComponent; @MockBean private GithubMemberClient githubMemberClient; @@ -215,63 +214,6 @@ public void updateProfileWithUpdateCenterPosition() { assertEquals(0, savedMember.getSemesterParts().size()); } - @Test - @DisplayName("유저 프로필 조회 테스트 - 본인") - @Transactional - public void inquiryMyProfile() { - // given - authService.signUp(member, getInfoRequest()); - - // when - MemberInquiryProfileResponse response = memberService.inquiryProfile(member, null); - - // then - assertEquals("김준석", response.getName()); - assertEquals("인하대학교", response.getUniversityName()); - assertEquals(MemberRelation.MINE, response.getOwner()); - } - - @Test - @DisplayName("유저 프로필 조회 테스트 - 친구") - @Transactional - public void inquiryFriendProfile() { - // given - Member loginMember = createMember("222222", Role.CAMPUS_STAFF); - - authService.signUp(member, getInfoRequest()); - - friendRepository.save(Friend.builder() - .sender(loginMember) - .receiver(member) - .build()); - - // when - MemberInquiryProfileResponse response = memberService.inquiryProfile(loginMember, member.getId()); - - // then - assertEquals("김준석", response.getName()); - assertEquals("인하대학교", response.getUniversityName()); - assertEquals(MemberRelation.FRIEND, response.getOwner()); - } - - @Test - @DisplayName("유저 프로필 조회 테스트 - 그 외") - @Transactional - public void inquiryOthersProfile() { - // given - Member loginMember = createMember("222222", Role.CAMPUS_STAFF); - - authService.signUp(member, getInfoRequest()); - - // when - MemberInquiryProfileResponse response = memberService.inquiryProfile(loginMember, member.getId()); - - // then - assertEquals("김준석", response.getName()); - assertEquals("인하대학교", response.getUniversityName()); - assertEquals(MemberRelation.OTHERS, response.getOwner()); - } - @Test @DisplayName("포인트 관련 유저 정보 조회 테스트") @Transactional diff --git a/src/test/java/com/umc/networkingService/support/ControllerTestConfig.java b/src/test/java/com/umc/networkingService/support/ControllerTestConfig.java index dbb2317b..9561d72c 100644 --- a/src/test/java/com/umc/networkingService/support/ControllerTestConfig.java +++ b/src/test/java/com/umc/networkingService/support/ControllerTestConfig.java @@ -29,20 +29,20 @@ public abstract class ControllerTestConfig { @BeforeEach public void setUp() { - member = createMember(); + member = createMember("111111", Role.MEMBER); setToken(member); } - private Member createMember() { + protected Member createMember(String clientId, Role role) { return Member.builder() .id(UUID.randomUUID()) - .clientId("123456") + .clientId(clientId) .socialType(SocialType.KAKAO) - .role(Role.MEMBER) + .role(role) .build(); } - private void setToken(Member member) { + protected void setToken(Member member) { accessToken = jwtTokenProvider.generateAccessToken(member.getId()); refreshToken = jwtTokenProvider.generateRefreshToken(member.getId()); } From c4843b958a555955782c76183218746c660cc63d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Thu, 25 Jan 2024 00:10:52 +0900 Subject: [PATCH 06/17] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20API=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/FriendServiceIntegrationTest.java | 62 ++++++++++++++++++- .../service/MemberServiceIntegrationTest.java | 4 -- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java index 14a9a174..eb3ff0af 100644 --- a/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java +++ b/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java @@ -1,9 +1,69 @@ package com.umc.networkingService.domain.friend.service; +import com.umc.networkingService.domain.friend.dto.response.FriendIdResponse; +import com.umc.networkingService.domain.friend.entity.Friend; +import com.umc.networkingService.domain.friend.repository.FriendRepository; +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.member.service.MemberService; +import com.umc.networkingService.global.common.enums.Role; +import com.umc.networkingService.global.common.exception.ErrorCode; +import com.umc.networkingService.global.common.exception.RestApiException; +import com.umc.networkingService.support.ServiceIntegrationTestConfig; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + @DisplayName("Friend 서비스의 ") @SpringBootTest -public class FriendServiceIntegrationTest { +public class FriendServiceIntegrationTest extends ServiceIntegrationTestConfig { + + @Autowired + private FriendService friendService; + @Autowired + private MemberService memberService; + + @Autowired + private FriendRepository friendRepository; + + @Test + @DisplayName("친구 추가 테스트") + @Transactional + public void createNewFriend() { + // given + Member friend = createMember("222222", Role.MEMBER); + + // when + FriendIdResponse response = friendService.createNewFriend(member, friend.getId()); + + // then + Optional optionalFriend = friendRepository.findById(response.getFriendId()); + assertTrue(optionalFriend.isPresent()); + Friend savedFriend = optionalFriend.get(); + + assertEquals(member, savedFriend.getSender()); + assertEquals(friend, savedFriend.getReceiver()); + } + + @Test + @DisplayName("친구 추가 테스트") + @Transactional + public void createNewFriendWithAlreadyFriend() { + // given + Member friend = createMember("222222", Role.MEMBER); + + // when + RestApiException exception = assertThrows(RestApiException.class, + () -> friendService.createNewFriend(member, friend.getId())); + + // then + assertEquals(ErrorCode.ALREADY_FRIEND_RELATION, exception.getErrorCode()); + assertFalse(friendRepository.existsBySenderAndReceiver(member, friend)); + } } diff --git a/src/test/java/com/umc/networkingService/domain/member/service/MemberServiceIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/member/service/MemberServiceIntegrationTest.java index 148479d7..ecce77c3 100644 --- a/src/test/java/com/umc/networkingService/domain/member/service/MemberServiceIntegrationTest.java +++ b/src/test/java/com/umc/networkingService/domain/member/service/MemberServiceIntegrationTest.java @@ -1,8 +1,6 @@ package com.umc.networkingService.domain.member.service; -import com.umc.networkingService.domain.friend.entity.Friend; -import com.umc.networkingService.domain.friend.repository.FriendRepository; import com.umc.networkingService.domain.member.client.GithubMemberClient; import com.umc.networkingService.domain.member.dto.request.MemberUpdateMyProfileRequest; import com.umc.networkingService.domain.member.dto.request.MemberUpdateProfileRequest; @@ -49,8 +47,6 @@ public class MemberServiceIntegrationTest extends ServiceIntegrationTestConfig { @MockBean private S3FileComponent s3FileComponent; @MockBean private GithubMemberClient githubMemberClient; - - private MemberPoint createMemberPoint(PointType pointType) { return MemberPoint.builder() .member(member) From 71e9f9dbc45f9746e74cb2e1237ad14dd6b3418f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Thu, 25 Jan 2024 00:11:12 +0900 Subject: [PATCH 07/17] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../friend/controller/FriendController.java | 21 +++++++++++---- .../friend/repository/FriendRepository.java | 2 ++ .../domain/friend/service/FriendService.java | 1 + .../friend/service/FriendServiceImpl.java | 26 ++++++++++++++++--- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java b/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java index 0bd7b5e1..2a994d98 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java +++ b/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java @@ -12,10 +12,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.UUID; @@ -27,7 +24,7 @@ public class FriendController { private final FriendService friendService; - @Operation(summary = "친구 추가 API", description = "네이버, 카카오, 구글, 애플 로그인") + @Operation(summary = "친구 추가 API", description = "새로운 친구를 추가하는 API입니다.") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "성공"), @ApiResponse(responseCode = "MEMBER001", description = "존재하지 않는 멤버를 친구 추가한 경우 발생"), @@ -39,4 +36,18 @@ public BaseResponse createNewFriend(@CurrentMember Member memb @PathVariable UUID memberId) { return BaseResponse.onSuccess(friendService.createNewFriend(member, memberId)); } + + @Operation(summary = "친구 삭제 API", description = "친구 관계를 끊는 API입니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공"), + @ApiResponse(responseCode = "MEMBER001", description = "존재하지 않는 멤버를 친구 삭제한 경우 발생"), + @ApiResponse(responseCode = "FRIEND002", description = "친구 관계가 아닌데 삭제한 경우 발생") + }) + @Parameter(name = "memberId", in = ParameterIn.PATH, required = true, description = "친구 삭제할 멤버 id입니다.") + @DeleteMapping("/{memberId}") + public BaseResponse deleteFriend(@CurrentMember Member member, + @PathVariable UUID memberId) { + return BaseResponse.onSuccess(friendService.deleteFriend(member, memberId)); + } + } diff --git a/src/main/java/com/umc/networkingService/domain/friend/repository/FriendRepository.java b/src/main/java/com/umc/networkingService/domain/friend/repository/FriendRepository.java index 36366064..46d4f7b3 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/repository/FriendRepository.java +++ b/src/main/java/com/umc/networkingService/domain/friend/repository/FriendRepository.java @@ -4,8 +4,10 @@ import com.umc.networkingService.domain.member.entity.Member; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.Optional; import java.util.UUID; public interface FriendRepository extends JpaRepository { + Optional findBySenderAndReceiver(Member sender, Member receiver); boolean existsBySenderAndReceiver(Member sender, Member receiver); } diff --git a/src/main/java/com/umc/networkingService/domain/friend/service/FriendService.java b/src/main/java/com/umc/networkingService/domain/friend/service/FriendService.java index f9fb5d3f..4746174e 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/service/FriendService.java +++ b/src/main/java/com/umc/networkingService/domain/friend/service/FriendService.java @@ -7,5 +7,6 @@ public interface FriendService { FriendIdResponse createNewFriend(Member member, UUID memberId); + FriendIdResponse deleteFriend(Member member, UUID memberId); boolean checkFriend(Member sender, Member receiver); } diff --git a/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java b/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java index 1e0b9655..17f50b54 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java +++ b/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java @@ -29,13 +29,26 @@ public FriendIdResponse createNewFriend(Member member, UUID memberId) { Member friendMember = memberService.loadEntity(memberId); - // 이미 존재하는 경우 예외 처리 if (friendRepository.existsBySenderAndReceiver(loginMember, friendMember)) throw new RestApiException(ErrorCode.ALREADY_FRIEND_RELATION); - Friend friend = friendMapper.toFriend(loginMember, friendMember); + return createAndSaveNewFriend(loginMember, friendMember); + } + + // 친구 삭제 함수 + @Override + public FriendIdResponse deleteFriend(Member member, UUID memberId) { + Member loginMember = memberService.loadEntity(member.getId()); + + Member friendMember = memberService.loadEntity(memberId); - return new FriendIdResponse(friendRepository.save(friend).getId()); + // 존재하지 않을 경우 예외 처리 + Friend friend = friendRepository.findBySenderAndReceiver(loginMember, friendMember) + .orElseThrow(() -> new RestApiException(ErrorCode.NOT_FRIEND_RELATION)); + + friend.delete(); + + return new FriendIdResponse(friend.getId()); } // 친구 여부 확인 함수 @@ -43,4 +56,11 @@ public FriendIdResponse createNewFriend(Member member, UUID memberId) { public boolean checkFriend(Member sender, Member receiver) { return friendRepository.existsBySenderAndReceiver(sender, receiver); } + + private FriendIdResponse createAndSaveNewFriend(Member loginMember, Member friendMember) { + Friend friend = friendMapper.toFriend(loginMember, friendMember); + UUID savedFriendId = friendRepository.save(friend).getId(); + + return new FriendIdResponse(savedFriendId); + } } From db4473e53316c49f0abedb79af55383846c4ea43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Thu, 25 Jan 2024 00:20:33 +0900 Subject: [PATCH 08/17] =?UTF-8?q?feat:=20=EC=B9=9C=EA=B5=AC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20API=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FriendControllerTest.java | 23 +++++++++++ .../service/FriendServiceIntegrationTest.java | 39 ++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/umc/networkingService/domain/friend/controller/FriendControllerTest.java b/src/test/java/com/umc/networkingService/domain/friend/controller/FriendControllerTest.java index a8a150f9..3bf607a7 100644 --- a/src/test/java/com/umc/networkingService/domain/friend/controller/FriendControllerTest.java +++ b/src/test/java/com/umc/networkingService/domain/friend/controller/FriendControllerTest.java @@ -14,6 +14,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -44,4 +45,26 @@ public void createNewFriend() throws Exception { .andExpect(jsonPath("$.message").value("요청에 성공하였습니다.")) .andExpect(jsonPath("$.result.friendId").value(response.getFriendId().toString())); } + + @DisplayName("친구 삭제 API 테스트") + @Test + public void deleteFriend() throws Exception { + // given + createMember("222222", Role.MEMBER); + + FriendIdResponse response = new FriendIdResponse(UUID.randomUUID()); + + given(friendService.deleteFriend(any(), any())).willReturn(response); + given(memberRepository.findById(any(UUID.class))).willReturn(Optional.of(member)); + + // when & then + mockMvc.perform(delete("/friends/" + response.getFriendId()) + .header("Authorization", accessToken)) + .andDo(print()) // 응답 출력 + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("COMMON200")) + .andExpect(jsonPath("$.message").value("요청에 성공하였습니다.")) + .andExpect(jsonPath("$.result.friendId").value(response.getFriendId().toString())); + + } } diff --git a/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java index eb3ff0af..149f5bca 100644 --- a/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java +++ b/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java @@ -52,11 +52,14 @@ public void createNewFriend() { } @Test - @DisplayName("친구 추가 테스트") + @DisplayName("친구 추가 테스트 - 이미 친구인 경우") @Transactional public void createNewFriendWithAlreadyFriend() { // given Member friend = createMember("222222", Role.MEMBER); + friendRepository.save( + Friend.builder().sender(member).receiver(friend).build() + ); // when RestApiException exception = assertThrows(RestApiException.class, @@ -64,6 +67,40 @@ public void createNewFriendWithAlreadyFriend() { // then assertEquals(ErrorCode.ALREADY_FRIEND_RELATION, exception.getErrorCode()); + assertTrue(friendRepository.existsBySenderAndReceiver(member, friend)); + } + + @Test + @DisplayName("친구 삭제 테스트") + @Transactional + public void deleteFriend() { + // given + Member friend = createMember("222222", Role.MEMBER); + friendRepository.save( + Friend.builder().sender(member).receiver(friend).build() + ); + + // when + FriendIdResponse response = friendService.deleteFriend(member, friend.getId()); + + // then + Optional optionalFriend = friendRepository.findById(response.getFriendId()); + assertNotNull(optionalFriend.get().getDeletedAt()); + } + + @Test + @DisplayName("친구 삭제 테스트 - 친구가 아닌 상태") + @Transactional + public void deleteFriendWithNotFriend() { + // given + Member friend = createMember("222222", Role.MEMBER); + + // when + RestApiException exception = assertThrows(RestApiException.class, + () -> friendService.deleteFriend(member, friend.getId())); + + // then + assertEquals(ErrorCode.NOT_FRIEND_RELATION, exception.getErrorCode()); assertFalse(friendRepository.existsBySenderAndReceiver(member, friend)); } } From 421534e9403f46bff3f8add39d796bbb830ea650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Thu, 25 Jan 2024 00:35:08 +0900 Subject: [PATCH 09/17] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=20=EC=BF=BC=EB=A6=AC=20=EB=B0=8F=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/repository/MemberRepository.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/com/umc/networkingService/domain/member/repository/MemberRepository.java b/src/main/java/com/umc/networkingService/domain/member/repository/MemberRepository.java index 46ae0096..58e8b43b 100644 --- a/src/main/java/com/umc/networkingService/domain/member/repository/MemberRepository.java +++ b/src/main/java/com/umc/networkingService/domain/member/repository/MemberRepository.java @@ -3,17 +3,14 @@ import com.umc.networkingService.domain.member.entity.Member; import com.umc.networkingService.domain.member.entity.SocialType; import com.umc.networkingService.domain.university.entity.University; -import io.lettuce.core.dynamic.annotation.Param; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; import java.util.List; import java.util.Optional; import java.util.UUID; public interface MemberRepository extends JpaRepository { - @Query(value = "select m from Member m where m.id = :memberId and m.deletedAt is null") - Optional findById(@Param("memberId") UUID memberId); + Optional findByClientIdAndSocialType(String clientId, SocialType socialType); List findAllByUniversityOrderByContributionPointDesc(University university); List findAllByNicknameAndName(String nickname, String name); From ad45ebc08e982bbbdf672e4d8102e369ff3f2eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Thu, 25 Jan 2024 00:57:14 +0900 Subject: [PATCH 10/17] =?UTF-8?q?feat:=20Session=EA=B3=BC=20Member=20?= =?UTF-8?q?=EC=96=91=EB=B0=A9=ED=96=A5=20=EB=A7=A4=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/networkingService/domain/member/entity/Member.java | 6 +++++- .../networkingService/domain/session/entity/Session.java | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/umc/networkingService/domain/member/entity/Member.java b/src/main/java/com/umc/networkingService/domain/member/entity/Member.java index 024949df..1dc0fd30 100644 --- a/src/main/java/com/umc/networkingService/domain/member/entity/Member.java +++ b/src/main/java/com/umc/networkingService/domain/member/entity/Member.java @@ -2,6 +2,7 @@ import com.umc.networkingService.domain.branch.entity.Branch; import com.umc.networkingService.domain.member.dto.request.MemberUpdateMyProfileRequest; +import com.umc.networkingService.domain.session.entity.Session; import com.umc.networkingService.domain.university.entity.University; import com.umc.networkingService.global.common.base.BaseEntity; import com.umc.networkingService.global.common.enums.Role; @@ -72,7 +73,10 @@ public class Member extends BaseEntity { private String gitNickname; - private String notionLink; + private String notionLink; + + @OneToOne(mappedBy = "member", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private Session session; public void setMemberInfo(String name, String nickname, University university, Branch branch) { this.name = name; diff --git a/src/main/java/com/umc/networkingService/domain/session/entity/Session.java b/src/main/java/com/umc/networkingService/domain/session/entity/Session.java index 5bbe3c59..2601d986 100644 --- a/src/main/java/com/umc/networkingService/domain/session/entity/Session.java +++ b/src/main/java/com/umc/networkingService/domain/session/entity/Session.java @@ -24,6 +24,7 @@ public class Session extends BaseEntity { private UUID id; @OneToOne(fetch = FetchType.LAZY) + @JoinColumn private Member member; private LocalDateTime lastActiveTime; From 90146c69f123db5216f4d0403aaa39589a09e154 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Thu, 25 Jan 2024 02:06:06 +0900 Subject: [PATCH 11/17] =?UTF-8?q?feat:=20Session=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=82=AD=EC=A0=9C=20=EB=B0=8F=20=EB=A9=A4=EB=B2=84?= =?UTF-8?q?=20lastActiveTime=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/entity/Member.java | 10 ++++-- .../domain/session/entity/Session.java | 35 ------------------- 2 files changed, 7 insertions(+), 38 deletions(-) delete mode 100644 src/main/java/com/umc/networkingService/domain/session/entity/Session.java diff --git a/src/main/java/com/umc/networkingService/domain/member/entity/Member.java b/src/main/java/com/umc/networkingService/domain/member/entity/Member.java index 1dc0fd30..42e1c1ed 100644 --- a/src/main/java/com/umc/networkingService/domain/member/entity/Member.java +++ b/src/main/java/com/umc/networkingService/domain/member/entity/Member.java @@ -2,7 +2,6 @@ import com.umc.networkingService.domain.branch.entity.Branch; import com.umc.networkingService.domain.member.dto.request.MemberUpdateMyProfileRequest; -import com.umc.networkingService.domain.session.entity.Session; import com.umc.networkingService.domain.university.entity.University; import com.umc.networkingService.global.common.base.BaseEntity; import com.umc.networkingService.global.common.enums.Role; @@ -13,6 +12,7 @@ import org.hibernate.annotations.SQLRestriction; import org.hibernate.annotations.UuidGenerator; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -75,8 +75,8 @@ public class Member extends BaseEntity { private String notionLink; - @OneToOne(mappedBy = "member", cascade = CascadeType.ALL, fetch = FetchType.LAZY) - private Session session; + // 가장 최근 호출 시간 + private LocalDateTime lastActiveTime; public void setMemberInfo(String name, String nickname, University university, Branch branch) { this.name = name; @@ -111,4 +111,8 @@ public void updateContributionPoint(Long usedPoint) { public void updateRole(Role role) { this.role = role; } + + public void updateLastActiveTime(LocalDateTime lastActiveTime) { + this.lastActiveTime = lastActiveTime; + } } diff --git a/src/main/java/com/umc/networkingService/domain/session/entity/Session.java b/src/main/java/com/umc/networkingService/domain/session/entity/Session.java deleted file mode 100644 index 2601d986..00000000 --- a/src/main/java/com/umc/networkingService/domain/session/entity/Session.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.umc.networkingService.domain.session.entity; - -import com.umc.networkingService.domain.member.entity.Member; -import com.umc.networkingService.global.common.base.BaseEntity; -import jakarta.persistence.*; -import lombok.*; -import org.hibernate.annotations.DynamicInsert; -import org.hibernate.annotations.SQLRestriction; -import org.hibernate.annotations.UuidGenerator; - -import java.time.LocalDateTime; -import java.util.UUID; - -@Getter -@Entity -@Builder -@AllArgsConstructor -@NoArgsConstructor(access= AccessLevel.PROTECTED) -@SQLRestriction("deleted_at is null") -@DynamicInsert -public class Session extends BaseEntity { - @Id - @UuidGenerator - private UUID id; - - @OneToOne(fetch = FetchType.LAZY) - @JoinColumn - private Member member; - - private LocalDateTime lastActiveTime; - - public void updateLastActiveTime(LocalDateTime lastActiveTime) { - this.lastActiveTime = lastActiveTime; - } -} From 7b0ec4b519b636f58c71dc88e495d4326c49af48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Thu, 25 Jan 2024 02:07:14 +0900 Subject: [PATCH 12/17] =?UTF-8?q?chore:=20=EC=A0=91=EC=86=8D/=EB=AF=B8?= =?UTF-8?q?=EC=A0=91=EC=86=8D=20=EC=B9=9C=EA=B5=AC=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?API=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../friend/controller/FriendController.java | 25 ++++++++++++++++++- .../dto/response/FriendInfoResponse.java | 25 +++++++++++++++++++ .../FriendInquiryByStatusResponse.java | 17 +++++++++++++ .../domain/friend/service/FriendService.java | 3 +++ .../friend/service/FriendServiceImpl.java | 8 ++++++ 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInfoResponse.java create mode 100644 src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInquiryByStatusResponse.java diff --git a/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java b/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java index 2a994d98..4ebf4eae 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java +++ b/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java @@ -2,18 +2,25 @@ import com.umc.networkingService.config.security.auth.CurrentMember; import com.umc.networkingService.domain.friend.dto.response.FriendIdResponse; +import com.umc.networkingService.domain.friend.dto.response.FriendInfoResponse; +import com.umc.networkingService.domain.friend.dto.response.FriendInquiryByStatusResponse; import com.umc.networkingService.domain.friend.service.FriendService; import com.umc.networkingService.domain.member.entity.Member; import com.umc.networkingService.global.common.base.BaseResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.web.PageableDefault; import org.springframework.web.bind.annotation.*; +import java.util.List; import java.util.UUID; @Tag(name = "친구 API", description = "친구 관련 API") @@ -37,7 +44,7 @@ public BaseResponse createNewFriend(@CurrentMember Member memb return BaseResponse.onSuccess(friendService.createNewFriend(member, memberId)); } - @Operation(summary = "친구 삭제 API", description = "친구 관계를 끊는 API입니다.") + @Operation(summary = "친구 삭제 API", description = "친구 관계를 삭제하는 API입니다.") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "성공"), @ApiResponse(responseCode = "MEMBER001", description = "존재하지 않는 멤버를 친구 삭제한 경우 발생"), @@ -50,4 +57,20 @@ public BaseResponse deleteFriend(@CurrentMember Member member, return BaseResponse.onSuccess(friendService.deleteFriend(member, memberId)); } + @Operation(summary = "접속/비접속 중인 친구 목록 조회 API", description = "친구 관계인 멤버 중 접속 또는 비접속 중인 멤버 조회 API입니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공") + }) + @Parameters(value = { + @Parameter(name = "status", required = true, description = "접속 상태입니다."), + @Parameter(name = "size", description = "한 페이지 당 데이터 개수입니다.(미입력 시 20개)") + }) + @GetMapping + public BaseResponse inquiryFriendsByStatus( + @CurrentMember Member member, + @RequestParam boolean status, + @PageableDefault(page = 1, sort = "nickname", direction = Sort.Direction.ASC) Pageable pageable) { + return BaseResponse.onSuccess(friendService.inquiryFriendsByStatus(member, status, pageable)); + } + } diff --git a/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInfoResponse.java b/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInfoResponse.java new file mode 100644 index 00000000..b77c03f2 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInfoResponse.java @@ -0,0 +1,25 @@ +package com.umc.networkingService.domain.friend.dto.response; + +import com.umc.networkingService.domain.member.dto.SemesterPartInfo; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.UUID; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class FriendInfoResponse { + private UUID memberId; + private String nickname; + private String name; + private String profileImage; + private String universityName; + private List campusPositions; + private List centerPositions; + private List semesterParts; +} diff --git a/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInquiryByStatusResponse.java b/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInquiryByStatusResponse.java new file mode 100644 index 00000000..83340c42 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInquiryByStatusResponse.java @@ -0,0 +1,17 @@ +package com.umc.networkingService.domain.friend.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class FriendInquiryByStatusResponse { + private List friends; + private boolean hasNext; +} diff --git a/src/main/java/com/umc/networkingService/domain/friend/service/FriendService.java b/src/main/java/com/umc/networkingService/domain/friend/service/FriendService.java index 4746174e..06ac25b1 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/service/FriendService.java +++ b/src/main/java/com/umc/networkingService/domain/friend/service/FriendService.java @@ -1,12 +1,15 @@ package com.umc.networkingService.domain.friend.service; import com.umc.networkingService.domain.friend.dto.response.FriendIdResponse; +import com.umc.networkingService.domain.friend.dto.response.FriendInquiryByStatusResponse; import com.umc.networkingService.domain.member.entity.Member; +import org.springframework.data.domain.Pageable; import java.util.UUID; public interface FriendService { FriendIdResponse createNewFriend(Member member, UUID memberId); FriendIdResponse deleteFriend(Member member, UUID memberId); + FriendInquiryByStatusResponse inquiryFriendsByStatus(Member member, boolean status, Pageable pageable); boolean checkFriend(Member sender, Member receiver); } diff --git a/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java b/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java index 17f50b54..94951a1c 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java +++ b/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java @@ -1,6 +1,7 @@ package com.umc.networkingService.domain.friend.service; import com.umc.networkingService.domain.friend.dto.response.FriendIdResponse; +import com.umc.networkingService.domain.friend.dto.response.FriendInquiryByStatusResponse; import com.umc.networkingService.domain.friend.entity.Friend; import com.umc.networkingService.domain.friend.mapper.FriendMapper; import com.umc.networkingService.domain.friend.repository.FriendRepository; @@ -9,6 +10,7 @@ import com.umc.networkingService.global.common.exception.ErrorCode; import com.umc.networkingService.global.common.exception.RestApiException; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import java.util.UUID; @@ -51,6 +53,12 @@ public FriendIdResponse deleteFriend(Member member, UUID memberId) { return new FriendIdResponse(friend.getId()); } + @Override + public FriendInquiryByStatusResponse inquiryFriendsByStatus(Member member, boolean status, Pageable pageable) { + + return null; + } + // 친구 여부 확인 함수 @Override public boolean checkFriend(Member sender, Member receiver) { From 4cc11b4d216d587b53422dc81b331fac83194b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Fri, 26 Jan 2024 20:30:37 +0900 Subject: [PATCH 13/17] =?UTF-8?q?feat:=20=EC=A0=91=EC=86=8D=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EC=B9=9C=EA=B5=AC=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../friend/controller/FriendController.java | 1 - .../dto/response/FriendInfoResponse.java | 25 ------------------- .../FriendInquiryByStatusResponse.java | 19 +++++++++++++- .../domain/friend/mapper/FriendMapper.java | 21 ++++++++++++++++ .../friend/repository/FriendRepository.java | 13 ++++++++++ .../friend/service/FriendServiceImpl.java | 19 +++++++++++++- .../member/controller/MemberController.java | 3 ++- .../domain/member/service/MemberService.java | 3 +++ .../member/service/MemberServiceImpl.java | 3 ++- 9 files changed, 77 insertions(+), 30 deletions(-) delete mode 100644 src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInfoResponse.java diff --git a/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java b/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java index 4ebf4eae..2f46d1cc 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java +++ b/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java @@ -2,7 +2,6 @@ import com.umc.networkingService.config.security.auth.CurrentMember; import com.umc.networkingService.domain.friend.dto.response.FriendIdResponse; -import com.umc.networkingService.domain.friend.dto.response.FriendInfoResponse; import com.umc.networkingService.domain.friend.dto.response.FriendInquiryByStatusResponse; import com.umc.networkingService.domain.friend.service.FriendService; import com.umc.networkingService.domain.member.entity.Member; diff --git a/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInfoResponse.java b/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInfoResponse.java deleted file mode 100644 index b77c03f2..00000000 --- a/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInfoResponse.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.umc.networkingService.domain.friend.dto.response; - -import com.umc.networkingService.domain.member.dto.SemesterPartInfo; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.util.List; -import java.util.UUID; - -@Getter -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class FriendInfoResponse { - private UUID memberId; - private String nickname; - private String name; - private String profileImage; - private String universityName; - private List campusPositions; - private List centerPositions; - private List semesterParts; -} diff --git a/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInquiryByStatusResponse.java b/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInquiryByStatusResponse.java index 83340c42..82741f6b 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInquiryByStatusResponse.java +++ b/src/main/java/com/umc/networkingService/domain/friend/dto/response/FriendInquiryByStatusResponse.java @@ -1,17 +1,34 @@ package com.umc.networkingService.domain.friend.dto.response; +import com.umc.networkingService.domain.member.dto.SemesterPartInfo; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import java.util.List; +import java.util.UUID; @Getter @Builder @AllArgsConstructor @NoArgsConstructor public class FriendInquiryByStatusResponse { - private List friends; + private List friends; private boolean hasNext; + + @Getter + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class FriendInfo { + private UUID memberId; + private String nickname; + private String name; + private String profileImage; + private String universityName; + private List campusPositions; + private List centerPositions; + private List semesterParts; + } } diff --git a/src/main/java/com/umc/networkingService/domain/friend/mapper/FriendMapper.java b/src/main/java/com/umc/networkingService/domain/friend/mapper/FriendMapper.java index 6c83529d..aa030ca8 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/mapper/FriendMapper.java +++ b/src/main/java/com/umc/networkingService/domain/friend/mapper/FriendMapper.java @@ -1,9 +1,13 @@ package com.umc.networkingService.domain.friend.mapper; +import com.umc.networkingService.domain.friend.dto.response.FriendInquiryByStatusResponse; import com.umc.networkingService.domain.friend.entity.Friend; +import com.umc.networkingService.domain.member.dto.SemesterPartInfo; import com.umc.networkingService.domain.member.entity.Member; import org.springframework.stereotype.Component; +import java.util.List; + @Component public class FriendMapper { @@ -13,4 +17,21 @@ public Friend toFriend(Member sender, Member receiver) { .receiver(receiver) .build(); } + + public FriendInquiryByStatusResponse.FriendInfo toFriendInfo(Member member, + List campusPositions, + List centerPositions, + List semesterParts) { + return FriendInquiryByStatusResponse.FriendInfo.builder() + .memberId(member.getId()) + .nickname(member.getNickname()) + .name(member.getName()) + .profileImage(member.getProfileImage()) + .universityName(member.getUniversity().getName()) + .campusPositions(campusPositions) + .centerPositions(centerPositions) + .semesterParts(semesterParts) + .build(); + + } } diff --git a/src/main/java/com/umc/networkingService/domain/friend/repository/FriendRepository.java b/src/main/java/com/umc/networkingService/domain/friend/repository/FriendRepository.java index 46d4f7b3..c487f1d8 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/repository/FriendRepository.java +++ b/src/main/java/com/umc/networkingService/domain/friend/repository/FriendRepository.java @@ -2,12 +2,25 @@ import com.umc.networkingService.domain.friend.entity.Friend; import com.umc.networkingService.domain.member.entity.Member; +import io.lettuce.core.dynamic.annotation.Param; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import java.time.LocalDateTime; import java.util.Optional; import java.util.UUID; public interface FriendRepository extends JpaRepository { Optional findBySenderAndReceiver(Member sender, Member receiver); boolean existsBySenderAndReceiver(Member sender, Member receiver); + + @Query("SELECT f.receiver FROM Friend f WHERE f.sender = :member AND " + + "(:status = true AND f.receiver.lastActiveTime >= :fiveMinutesAgo OR " + + ":status = false AND f.receiver.lastActiveTime < :fiveMinutesAgo)") + Page findFriendsByStatus(@Param("member") Member member, + @Param("status") boolean status, + @Param("fiveMinutesAgo") LocalDateTime fiveMinutesAgo, + Pageable pageable); } diff --git a/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java b/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java index 94951a1c..8e069906 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java +++ b/src/main/java/com/umc/networkingService/domain/friend/service/FriendServiceImpl.java @@ -6,13 +6,18 @@ import com.umc.networkingService.domain.friend.mapper.FriendMapper; import com.umc.networkingService.domain.friend.repository.FriendRepository; import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.member.entity.PositionType; +import com.umc.networkingService.domain.member.mapper.MemberMapper; import com.umc.networkingService.domain.member.service.MemberService; import com.umc.networkingService.global.common.exception.ErrorCode; import com.umc.networkingService.global.common.exception.RestApiException; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; +import java.util.List; import java.util.UUID; @Service @@ -21,6 +26,7 @@ public class FriendServiceImpl implements FriendService { private final FriendRepository friendRepository; private final FriendMapper friendMapper; + private final MemberMapper memberMapper; private final MemberService memberService; @@ -55,8 +61,19 @@ public FriendIdResponse deleteFriend(Member member, UUID memberId) { @Override public FriendInquiryByStatusResponse inquiryFriendsByStatus(Member member, boolean status, Pageable pageable) { + LocalDateTime fiveMinutesAgo = LocalDateTime.now().minusMinutes(5); + Page friends = friendRepository.findFriendsByStatus(member, status, fiveMinutesAgo, pageable); - return null; + List friendInfos = friends.stream() + .map(friend -> friendMapper.toFriendInfo( + friend, + memberService.getPositionNamesByType(friend, PositionType.CAMPUS), + memberService.getPositionNamesByType(friend, PositionType.CENTER), + memberMapper.toSemesterPartInfos(friend.getSemesterParts()) + )).toList(); + + + return new FriendInquiryByStatusResponse(friendInfos, friends.hasNext()); } // 친구 여부 확인 함수 diff --git a/src/main/java/com/umc/networkingService/domain/member/controller/MemberController.java b/src/main/java/com/umc/networkingService/domain/member/controller/MemberController.java index 6ce08803..6de5895e 100644 --- a/src/main/java/com/umc/networkingService/domain/member/controller/MemberController.java +++ b/src/main/java/com/umc/networkingService/domain/member/controller/MemberController.java @@ -15,6 +15,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -34,7 +35,7 @@ public class MemberController { @ApiResponse(responseCode = "COMMON200", description = "성공"), @ApiResponse(responseCode = "IMAGE001", description = "이미지 S3 업로드 실패할 경우 발생") }) - @PostMapping("/update") + @PostMapping(value = "/update", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public BaseResponse updateMyProfile(@CurrentMember Member member, @RequestPart(value = "profileImage", required = false) MultipartFile profileImage, @RequestPart MemberUpdateMyProfileRequest request) { diff --git a/src/main/java/com/umc/networkingService/domain/member/service/MemberService.java b/src/main/java/com/umc/networkingService/domain/member/service/MemberService.java index 9d9d6fbc..647b1475 100644 --- a/src/main/java/com/umc/networkingService/domain/member/service/MemberService.java +++ b/src/main/java/com/umc/networkingService/domain/member/service/MemberService.java @@ -4,9 +4,11 @@ import com.umc.networkingService.domain.member.dto.request.MemberUpdateProfileRequest; import com.umc.networkingService.domain.member.dto.response.*; import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.member.entity.PositionType; import com.umc.networkingService.global.common.base.EntityLoader; import org.springframework.web.multipart.MultipartFile; +import java.util.List; import java.util.UUID; public interface MemberService extends EntityLoader { @@ -18,5 +20,6 @@ public interface MemberService extends EntityLoader { MemberInquiryPointsResponse inquiryMemberPoints(Member member); MemberSearchInfosResponse searchMemberInfo(Member member, String keyword); void updateMemberActiveTime(UUID memberId); + List getPositionNamesByType(Member member, PositionType type); Member saveEntity(Member member); } diff --git a/src/main/java/com/umc/networkingService/domain/member/service/MemberServiceImpl.java b/src/main/java/com/umc/networkingService/domain/member/service/MemberServiceImpl.java index 7cab3e30..05a7029b 100644 --- a/src/main/java/com/umc/networkingService/domain/member/service/MemberServiceImpl.java +++ b/src/main/java/com/umc/networkingService/domain/member/service/MemberServiceImpl.java @@ -254,7 +254,8 @@ private String[] validateKeyword(final String keyword) { } // 타입에 따른 직책 찾기 함수 - private List getPositionNamesByType(Member member, PositionType type) { + @Override + public List getPositionNamesByType(Member member, PositionType type) { return member.getPositions().stream() .filter(position -> position.getType() == type) .map(MemberPosition::getName) From f0fb7b72522eca7cacbce53dd2fb61488e09f32e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Sat, 27 Jan 2024 18:59:33 +0900 Subject: [PATCH 14/17] =?UTF-8?q?fix:=20=EC=A0=91=EC=86=8D/=EB=B9=84?= =?UTF-8?q?=EC=A0=91=EC=86=8D=20=EC=A4=91=EC=9D=B8=20=EC=B9=9C=EA=B5=AC=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20API=20=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20=ED=95=84=EB=93=9C=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/friend/controller/FriendController.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java b/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java index 2f46d1cc..eb0c86fe 100644 --- a/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java +++ b/src/main/java/com/umc/networkingService/domain/friend/controller/FriendController.java @@ -17,6 +17,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.web.PageableDefault; +import org.springframework.security.core.parameters.P; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -32,7 +33,7 @@ public class FriendController { @Operation(summary = "친구 추가 API", description = "새로운 친구를 추가하는 API입니다.") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "성공"), + @ApiResponse(responseCode = "COMMON200", description = "성공"), @ApiResponse(responseCode = "MEMBER001", description = "존재하지 않는 멤버를 친구 추가한 경우 발생"), @ApiResponse(responseCode = "FRIEND001", description = "이미 친구 관계일 경우 발생") }) @@ -45,7 +46,7 @@ public BaseResponse createNewFriend(@CurrentMember Member memb @Operation(summary = "친구 삭제 API", description = "친구 관계를 삭제하는 API입니다.") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "성공"), + @ApiResponse(responseCode = "COMMON200", description = "성공"), @ApiResponse(responseCode = "MEMBER001", description = "존재하지 않는 멤버를 친구 삭제한 경우 발생"), @ApiResponse(responseCode = "FRIEND002", description = "친구 관계가 아닌데 삭제한 경우 발생") }) @@ -58,17 +59,18 @@ public BaseResponse deleteFriend(@CurrentMember Member member, @Operation(summary = "접속/비접속 중인 친구 목록 조회 API", description = "친구 관계인 멤버 중 접속 또는 비접속 중인 멤버 조회 API입니다.") @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "성공") + @ApiResponse(responseCode = "COMMON200", description = "성공") }) @Parameters(value = { @Parameter(name = "status", required = true, description = "접속 상태입니다."), - @Parameter(name = "size", description = "한 페이지 당 데이터 개수입니다.(미입력 시 20개)") + @Parameter(name = "pageable", hidden = true), + @Parameter(name = "size", required = true, description = "한 페이지에 포함되는 목록 개수입니다.") }) @GetMapping public BaseResponse inquiryFriendsByStatus( @CurrentMember Member member, @RequestParam boolean status, - @PageableDefault(page = 1, sort = "nickname", direction = Sort.Direction.ASC) Pageable pageable) { + @PageableDefault(page = 1, sort = "receiver.nickname", direction = Sort.Direction.ASC) Pageable pageable) { return BaseResponse.onSuccess(friendService.inquiryFriendsByStatus(member, status, pageable)); } From dff0f6921e3ba1322eb35ce53bd80ed1f614905a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Sat, 27 Jan 2024 18:59:53 +0900 Subject: [PATCH 15/17] =?UTF-8?q?feat:=20=EC=A0=91=EC=86=8D/=EB=B9=84?= =?UTF-8?q?=EC=A0=91=EC=86=8D=20=EC=A4=91=EC=9D=B8=20=EC=B9=9C=EA=B5=AC=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20API=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FriendControllerTest.java | 41 +++++++++- .../service/FriendServiceIntegrationTest.java | 80 ++++++++++++++++++- .../FriendShipServiceImplIntegrationTest.java | 8 +- .../controller/InviteControllerTest.java | 2 +- .../service/AuthServiceIntegrationTest.java | 3 +- .../service/MemberServiceIntegrationTest.java | 23 +++--- .../support/ServiceIntegrationTestConfig.java | 10 +-- 7 files changed, 140 insertions(+), 27 deletions(-) diff --git a/src/test/java/com/umc/networkingService/domain/friend/controller/FriendControllerTest.java b/src/test/java/com/umc/networkingService/domain/friend/controller/FriendControllerTest.java index 3bf607a7..23c96e73 100644 --- a/src/test/java/com/umc/networkingService/domain/friend/controller/FriendControllerTest.java +++ b/src/test/java/com/umc/networkingService/domain/friend/controller/FriendControllerTest.java @@ -1,21 +1,26 @@ package com.umc.networkingService.domain.friend.controller; import com.umc.networkingService.domain.friend.dto.response.FriendIdResponse; +import com.umc.networkingService.domain.friend.dto.response.FriendInquiryByStatusResponse; import com.umc.networkingService.domain.friend.service.FriendService; +import com.umc.networkingService.domain.member.dto.SemesterPartInfo; import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.global.common.enums.Part; import com.umc.networkingService.global.common.enums.Role; +import com.umc.networkingService.global.common.enums.Semester; import com.umc.networkingService.support.ControllerTestConfig; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; +import java.util.List; import java.util.Optional; import java.util.UUID; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -67,4 +72,36 @@ public void deleteFriend() throws Exception { .andExpect(jsonPath("$.result.friendId").value(response.getFriendId().toString())); } + + @DisplayName("접속/미접속 친구 조회 API 테스트") + @Test + public void inquiryFriendsByStatus() throws Exception { + // given + List friends = List.of( + new FriendInquiryByStatusResponse.FriendInfo(UUID.randomUUID(), "벡스", "김준석", null, "인하대학교", List.of("회장"), List.of(), + List.of(new SemesterPartInfo(Part.ANDROID, Semester.THIRD), new SemesterPartInfo(Part.SPRING, Semester.FOURTH), new SemesterPartInfo(Part.SPRING, Semester.FIFTH))), + new FriendInquiryByStatusResponse.FriendInfo(UUID.randomUUID(), "하나", "심세원", null, "가천대학교", List.of(), List.of(), + List.of(new SemesterPartInfo(Part.ANDROID, Semester.FOURTH), new SemesterPartInfo(Part.SPRING, Semester.FIFTH))), + new FriendInquiryByStatusResponse.FriendInfo(UUID.randomUUID(), "밈보", "김보민", null, "인하대학교", List.of("iOS 파트장"), List.of(), + List.of(new SemesterPartInfo(Part.IOS, Semester.FOURTH), new SemesterPartInfo(Part.SPRING, Semester.FIFTH))) + ); + FriendInquiryByStatusResponse response = FriendInquiryByStatusResponse.builder() + .friends(friends) + .hasNext(false) + .build(); + + given(friendService.inquiryFriendsByStatus(any(), eq(true), any())).willReturn(response); + given(memberRepository.findById(any(UUID.class))).willReturn(Optional.of(member)); + + // when & then + mockMvc.perform(get("/friends") + .param("size", "3") + .param("status", String.valueOf(true)) + .header("Authorization", accessToken)) + .andDo(print()) // 응답 출력 + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("COMMON200")) + .andExpect(jsonPath("$.message").value("요청에 성공하였습니다.")) + .andExpect(jsonPath("$.result.friends.size()").value(response.getFriends().size())); + } } diff --git a/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java index 149f5bca..04b7c9c5 100644 --- a/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java +++ b/src/test/java/com/umc/networkingService/domain/friend/service/FriendServiceIntegrationTest.java @@ -1,10 +1,17 @@ package com.umc.networkingService.domain.friend.service; +import com.umc.networkingService.domain.branch.entity.Branch; import com.umc.networkingService.domain.friend.dto.response.FriendIdResponse; +import com.umc.networkingService.domain.friend.dto.response.FriendInquiryByStatusResponse; import com.umc.networkingService.domain.friend.entity.Friend; import com.umc.networkingService.domain.friend.repository.FriendRepository; import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.member.entity.MemberPosition; +import com.umc.networkingService.domain.member.entity.SemesterPart; +import com.umc.networkingService.domain.member.entity.SocialType; +import com.umc.networkingService.domain.member.service.AuthService; import com.umc.networkingService.domain.member.service.MemberService; +import com.umc.networkingService.domain.university.entity.University; import com.umc.networkingService.global.common.enums.Role; import com.umc.networkingService.global.common.exception.ErrorCode; import com.umc.networkingService.global.common.exception.RestApiException; @@ -13,8 +20,13 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDateTime; +import java.util.List; import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; @@ -27,11 +39,24 @@ public class FriendServiceIntegrationTest extends ServiceIntegrationTestConfig { @Autowired private FriendService friendService; @Autowired - private MemberService memberService; + private AuthService authService; @Autowired private FriendRepository friendRepository; + private void makeFriend(Member sender, Member receiver) { + friendRepository.save( + Friend.builder().sender(sender).receiver(receiver).build() + ); + } + + private Member createAndSignupFriend(String id, Role role, String name, String nickname, List titles, List hashtags, LocalDateTime lastActiveTime) { + Member friend = createMember(id, role); + authService.signUp(friend, getInfoRequest(name, nickname, titles, hashtags)); + friend.updateLastActiveTime(lastActiveTime); + return friend; + } + @Test @DisplayName("친구 추가 테스트") @Transactional @@ -76,9 +101,7 @@ public void createNewFriendWithAlreadyFriend() { public void deleteFriend() { // given Member friend = createMember("222222", Role.MEMBER); - friendRepository.save( - Friend.builder().sender(member).receiver(friend).build() - ); + makeFriend(member, friend); // when FriendIdResponse response = friendService.deleteFriend(member, friend.getId()); @@ -103,4 +126,53 @@ public void deleteFriendWithNotFriend() { assertEquals(ErrorCode.NOT_FRIEND_RELATION, exception.getErrorCode()); assertFalse(friendRepository.existsBySenderAndReceiver(member, friend)); } + + @Test + @DisplayName("접속 중인 친구 조회 테스트") + @Transactional + public void inquiryFriendsByStatusOnline() { + // given + Member onlineFriend1 = createAndSignupFriend("222222", Role.CAMPUS_STAFF, "이경수", "리버", List.of("iOS 파트장"), List.of(), LocalDateTime.now()); + makeFriend(member, onlineFriend1); + + Member onlineFriend2 = createAndSignupFriend("333333", Role.MEMBER, "박재우", "다재", List.of(), List.of(), LocalDateTime.now()); + makeFriend(member, onlineFriend2); + + Member offlineFriend1 = createAndSignupFriend("444444", Role.MEMBER, "김보민", "밈보", List.of(), List.of(), LocalDateTime.now().minusMinutes(10)); + makeFriend(member, offlineFriend1); + + Pageable pageable = PageRequest.of(0, 10, Sort.by("receiver.nickname").ascending()); + + // when + FriendInquiryByStatusResponse response = friendService.inquiryFriendsByStatus(member, true, pageable); + + // then + assertEquals(2, response.getFriends().size()); + assertEquals("다재", response.getFriends().get(0).getNickname()); + assertEquals("리버", response.getFriends().get(1).getNickname()); + } + + @Test + @DisplayName("미접속 중인 친구 조회 테스트") + @Transactional + public void inquiryFriendsByStatusOffline() { + // given + Member onlineFriend1 = createAndSignupFriend("222222", Role.CAMPUS_STAFF, "이경수", "리버", List.of("iOS 파트장"), List.of(), LocalDateTime.now()); + makeFriend(member, onlineFriend1); + + Member onlineFriend2 = createAndSignupFriend("333333", Role.MEMBER, "박재우", "다재", List.of(), List.of(), LocalDateTime.now()); + makeFriend(member, onlineFriend2); + + Member offlineFriend1 = createAndSignupFriend("444444", Role.MEMBER, "김보민", "밈보", List.of(), List.of(), LocalDateTime.now().minusMinutes(10)); + makeFriend(member, offlineFriend1); + + Pageable pageable = PageRequest.of(0, 10, Sort.by("receiver.nickname").ascending()); + + // when + FriendInquiryByStatusResponse response = friendService.inquiryFriendsByStatus(member, false, pageable); + + // then + assertEquals(1, response.getFriends().size()); + assertEquals("밈보", response.getFriends().get(0).getNickname()); + } } diff --git a/src/test/java/com/umc/networkingService/domain/friend/service/FriendShipServiceImplIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/friend/service/FriendShipServiceImplIntegrationTest.java index f781f0f2..c58261a5 100644 --- a/src/test/java/com/umc/networkingService/domain/friend/service/FriendShipServiceImplIntegrationTest.java +++ b/src/test/java/com/umc/networkingService/domain/friend/service/FriendShipServiceImplIntegrationTest.java @@ -14,6 +14,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; +import java.util.List; + import static org.junit.jupiter.api.Assertions.assertEquals; @DisplayName("FriendShip 서비스의 ") @@ -32,7 +34,7 @@ public class FriendShipServiceImplIntegrationTest extends ServiceIntegrationTest @Transactional public void inquiryMyProfile() { // given - authService.signUp(member, getInfoRequest()); + authService.signUp(member, getInfoRequest("김준석", "벡스", List.of("회장"), List.of())); // when MemberInquiryProfileResponse response = friendShipService.inquiryProfile(member, null); @@ -50,7 +52,7 @@ public void inquiryFriendProfile() { // given Member loginMember = createMember("222222", Role.CAMPUS_STAFF); - authService.signUp(member, getInfoRequest()); + authService.signUp(member, getInfoRequest("김준석", "벡스", List.of("회장"), List.of())); friendRepository.save(Friend.builder() .sender(loginMember) @@ -73,7 +75,7 @@ public void inquiryOthersProfile() { // given Member loginMember = createMember("222222", Role.CAMPUS_STAFF); - authService.signUp(member, getInfoRequest()); + authService.signUp(member, getInfoRequest("김준석", "벡스", List.of("회장"), List.of())); // when MemberInquiryProfileResponse response = friendShipService.inquiryProfile(loginMember, member.getId()); diff --git a/src/test/java/com/umc/networkingService/domain/invite/controller/InviteControllerTest.java b/src/test/java/com/umc/networkingService/domain/invite/controller/InviteControllerTest.java index b0d003c7..edee22f5 100644 --- a/src/test/java/com/umc/networkingService/domain/invite/controller/InviteControllerTest.java +++ b/src/test/java/com/umc/networkingService/domain/invite/controller/InviteControllerTest.java @@ -88,7 +88,7 @@ public void inquiryMyInviteCode() throws Exception { .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value("COMMON200")) .andExpect(jsonPath("$.message").value("요청에 성공하였습니다.")) - .andExpect(jsonPath("$.result").value(hasSize(response.getInvites().size()))); + .andExpect(jsonPath("$.result.invites").value(hasSize(response.getInvites().size()))); } @DisplayName("초대 코드 인증 API 테스트") diff --git a/src/test/java/com/umc/networkingService/domain/member/service/AuthServiceIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/member/service/AuthServiceIntegrationTest.java index 2c9fa894..a99d5f00 100644 --- a/src/test/java/com/umc/networkingService/domain/member/service/AuthServiceIntegrationTest.java +++ b/src/test/java/com/umc/networkingService/domain/member/service/AuthServiceIntegrationTest.java @@ -179,7 +179,8 @@ public void withdrawalTest() { authService.withdrawal(member); // then - assertFalse(memberRepository.findById(member.getId()).isPresent()); + Optional optionalMember = memberRepository.findById(member.getId()); + assertNotNull(optionalMember.get().getDeletedAt()); assertFalse(refreshTokenService.findByMemberId(member.getId()).isPresent()); } } diff --git a/src/test/java/com/umc/networkingService/domain/member/service/MemberServiceIntegrationTest.java b/src/test/java/com/umc/networkingService/domain/member/service/MemberServiceIntegrationTest.java index 86d32486..ff6440cd 100644 --- a/src/test/java/com/umc/networkingService/domain/member/service/MemberServiceIntegrationTest.java +++ b/src/test/java/com/umc/networkingService/domain/member/service/MemberServiceIntegrationTest.java @@ -27,6 +27,7 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.BDDMockito.given; @DisplayName("Member 서비스의 ") @@ -215,20 +216,20 @@ public void updateProfileWithUpdateCenterPosition() { @Transactional public void inquiryHomeInfo() { // given - authService.signUp(member, getInfoRequest()); + authService.signUp(member, getInfoRequest("김준석", "벡스", List.of("회장"), List.of())); member.updateContributionPoint(1000L); - Member universityMember1 = createMember("222222", Role.MEMBER); - authService.signUp(universityMember1, getInfoRequest()); + Member universityMember1 = createMember("222222", Role.CAMPUS_STAFF); + authService.signUp(universityMember1, getInfoRequest("이경수", "리버", List.of("iOS 파트장"), List.of())); universityMember1.updateContributionPoint(2000L); Member universityMember2 = createMember("333333", Role.MEMBER); - authService.signUp(universityMember2, getInfoRequest()); + authService.signUp(universityMember2, getInfoRequest("김보민", "밈보", List.of(), List.of())); universityMember2.updateContributionPoint(2000L); Member universityMember3 = createMember("444444", Role.MEMBER); - authService.signUp(universityMember3, getInfoRequest()); + authService.signUp(universityMember3, getInfoRequest("김수민", "루시", List.of(), List.of())); universityMember3.updateContributionPoint(3000L); Member universityMember4 = createMember("555555", Role.MEMBER); - authService.signUp(universityMember4, getInfoRequest()); + authService.signUp(universityMember4, getInfoRequest("박재우", "다재", List.of(), List.of())); universityMember4.updateContributionPoint(1000L); // when @@ -336,7 +337,7 @@ public void inquiryMemberPointsWithMultiple() { public void searchMemberInfo() { // given String keyword = "벡스/김준석"; - authService.signUp(member, getInfoRequest()); + authService.signUp(member, getInfoRequest("김준석", "벡스", List.of("회장"), List.of())); Member staff = createMember("222222", Role.CENTER_STAFF); @@ -355,10 +356,10 @@ public void searchMembersInfo() { // given String keyword = "벡스/김준석"; - authService.signUp(member, getInfoRequest()); + authService.signUp(member, getInfoRequest("김준석", "벡스", List.of("회장"), List.of())); Member anotherMember = createMember("222222", Role.CAMPUS_STAFF); - authService.signUp(anotherMember, getInfoRequest()); + authService.signUp(anotherMember, getInfoRequest("김준석", "벡스", List.of(), List.of())); Member staff = createMember("333333", Role.CENTER_STAFF); @@ -376,10 +377,10 @@ public void searchMembersInfoByLowRole() { // given String keyword = "벡스/김준석"; - authService.signUp(member, getInfoRequest()); + authService.signUp(member, getInfoRequest("김준석", "벡스", List.of("회장"), List.of())); Member anotherMember = createMember("222222", Role.TOTAL_STAFF); - authService.signUp(anotherMember, getInfoRequest()); + authService.signUp(anotherMember, getInfoRequest("김준석", "벡스", List.of(), List.of("회장"))); Member staff = createMember("333333", Role.CENTER_STAFF); diff --git a/src/test/java/com/umc/networkingService/support/ServiceIntegrationTestConfig.java b/src/test/java/com/umc/networkingService/support/ServiceIntegrationTestConfig.java index ca643260..f45a22bb 100644 --- a/src/test/java/com/umc/networkingService/support/ServiceIntegrationTestConfig.java +++ b/src/test/java/com/umc/networkingService/support/ServiceIntegrationTestConfig.java @@ -72,14 +72,14 @@ protected Member createMember(String clientId, Role role) { ); } - protected MemberSignUpRequest getInfoRequest() { + protected MemberSignUpRequest getInfoRequest(String name, String nickname, List campusPositions, List centerPositions) { return MemberSignUpRequest.builder() - .name("김준석") - .nickname("벡스") + .name(name) + .nickname(nickname) .universityName("인하대학교") .semesterParts(memberMapper.toSemesterPartInfos(createSemesterPart(member))) - .campusPositions(List.of("Android 파트장")) - .centerPositions(List.of()) + .campusPositions(campusPositions) + .centerPositions(centerPositions) .build(); } From 1f313bfac345384a08c7f0e32a851f0103928aef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Sat, 27 Jan 2024 19:08:52 +0900 Subject: [PATCH 16/17] =?UTF-8?q?feat:=20=EC=8A=A4=EC=9B=A8=EA=B1=B0?= =?UTF-8?q?=EC=97=90=EC=84=9C=20multipartfile=EA=B3=BC=20response=20?= =?UTF-8?q?=EB=8F=99=EC=8B=9C=20=EC=82=AC=EC=9A=A9=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EC=BB=A8=EB=B2=84=ED=84=B0=20=EC=83=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...MultipartJackson2HttpMessageConverter.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/main/java/com/umc/networkingService/global/common/base/swagger/MultipartJackson2HttpMessageConverter.java diff --git a/src/main/java/com/umc/networkingService/global/common/base/swagger/MultipartJackson2HttpMessageConverter.java b/src/main/java/com/umc/networkingService/global/common/base/swagger/MultipartJackson2HttpMessageConverter.java new file mode 100644 index 00000000..23c40bc1 --- /dev/null +++ b/src/main/java/com/umc/networkingService/global/common/base/swagger/MultipartJackson2HttpMessageConverter.java @@ -0,0 +1,31 @@ +package com.umc.networkingService.global.common.base.swagger; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Type; + +@Component +public class MultipartJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter { + + public MultipartJackson2HttpMessageConverter(ObjectMapper objectMapper) { + super(objectMapper, MediaType.APPLICATION_OCTET_STREAM); + } + + @Override + public boolean canWrite(Class clazz, MediaType mediaType) { + return false; + } + + @Override + public boolean canWrite(Type type, Class clazz, MediaType mediaType) { + return false; + } + + @Override + protected boolean canWrite(MediaType mediaType) { + return false; + } +} \ No newline at end of file From 684244ac6dde3e0d545221130924620527c31b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=A4=80=EC=8D=A8=ED=81=AC?= Date: Sat, 27 Jan 2024 19:40:38 +0900 Subject: [PATCH 17/17] =?UTF-8?q?docs:=20=EA=B9=83=ED=97=88=EB=B8=8C=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A1=B0=ED=9A=8C=20API=20respon?= =?UTF-8?q?se=20code=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/controller/MemberController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/umc/networkingService/domain/member/controller/MemberController.java b/src/main/java/com/umc/networkingService/domain/member/controller/MemberController.java index 6de5895e..6265c1ca 100644 --- a/src/main/java/com/umc/networkingService/domain/member/controller/MemberController.java +++ b/src/main/java/com/umc/networkingService/domain/member/controller/MemberController.java @@ -78,7 +78,7 @@ public BaseResponse authenticationGithub(@Curr @Operation(summary = "깃허브 데이터 조회 API", description = "깃허브 잔디 이미지를 조회하는 API입니다.") @ApiResponses( value = { @ApiResponse(responseCode = "COMMON200", description = "성공"), - @ApiResponse(responseCode = "AUTH008", description = "깃허브 인증이 안 된 사용자일 경우 발생") + @ApiResponse(responseCode = "MEMBER005", description = "깃허브 인증이 안 된 사용자일 경우 발생") }) @GetMapping("/github") public BaseResponse inquiryGithubImage(@CurrentMember Member member) {