diff --git a/src/main/java/com/sillim/recordit/feed/service/FeedLikeService.java b/src/main/java/com/sillim/recordit/feed/service/FeedLikeService.java index 1eb1276e..e4bbae36 100644 --- a/src/main/java/com/sillim/recordit/feed/service/FeedLikeService.java +++ b/src/main/java/com/sillim/recordit/feed/service/FeedLikeService.java @@ -34,7 +34,7 @@ public class FeedLikeService { ObjectOptimisticLockingFailureException.class, StaleObjectStateException.class }, - maxAttempts = 15, + maxAttempts = 20, backoff = @Backoff(delay = 30)) public void feedLike(Long feedId, Long memberId) { Feed feed = @@ -61,7 +61,7 @@ public void feedLike(Long feedId, Long memberId) { ObjectOptimisticLockingFailureException.class, StaleObjectStateException.class }, - maxAttempts = 15, + maxAttempts = 20, backoff = @Backoff(delay = 30)) public void feedUnlike(Long feedId, Long memberId) { feedRepository diff --git a/src/main/java/com/sillim/recordit/invite/controller/InviteController.java b/src/main/java/com/sillim/recordit/invite/controller/InviteController.java index 34879c22..caf1faf4 100644 --- a/src/main/java/com/sillim/recordit/invite/controller/InviteController.java +++ b/src/main/java/com/sillim/recordit/invite/controller/InviteController.java @@ -7,8 +7,10 @@ import com.sillim.recordit.invite.dto.response.InviteLinkResponse; import com.sillim.recordit.invite.service.InviteService; import com.sillim.recordit.member.domain.Member; +import com.sillim.recordit.member.dto.response.MemberListResponse; import com.sillim.recordit.member.service.MemberQueryService; import java.io.IOException; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -37,6 +39,17 @@ public ResponseEntity getInviteInfo(@PathVariable String inv calendar.getId(), calendar.getTitle(), member.getId(), member.getName())); } + @GetMapping("/followings") + public ResponseEntity> myFollowingList( + @RequestParam Long calendarId, @CurrentMember Member member) { + return ResponseEntity.ok( + inviteService + .searchFollowingsNotInvited(calendarId, member.getPersonalId()) + .stream() + .map(MemberListResponse::of) + .toList()); + } + @PostMapping("/members/{inviteMemberId}") public ResponseEntity inviteMember( @PathVariable Long inviteMemberId, diff --git a/src/main/java/com/sillim/recordit/invite/service/InviteService.java b/src/main/java/com/sillim/recordit/invite/service/InviteService.java index 042e9506..215a8e8d 100644 --- a/src/main/java/com/sillim/recordit/invite/service/InviteService.java +++ b/src/main/java/com/sillim/recordit/invite/service/InviteService.java @@ -1,6 +1,7 @@ package com.sillim.recordit.invite.service; import com.sillim.recordit.calendar.domain.Calendar; +import com.sillim.recordit.calendar.dto.response.CalendarMemberResponse; import com.sillim.recordit.calendar.service.CalendarMemberService; import com.sillim.recordit.calendar.service.CalendarQueryService; import com.sillim.recordit.global.exception.ErrorCode; @@ -12,10 +13,12 @@ import com.sillim.recordit.invite.repository.InviteLinkRepository; import com.sillim.recordit.invite.repository.InviteLogRepository; import com.sillim.recordit.member.domain.Member; +import com.sillim.recordit.member.service.MemberQueryService; import com.sillim.recordit.pushalarm.dto.PushMessage; import com.sillim.recordit.pushalarm.service.AlarmService; import java.time.LocalDateTime; import java.util.Base64; +import java.util.List; import java.util.Optional; import java.util.UUID; import lombok.RequiredArgsConstructor; @@ -32,6 +35,7 @@ public class InviteService { private final InviteLogRepository inviteLogRepository; private final AlarmService alarmService; private final CalendarMemberService calendarMemberService; + private final MemberQueryService memberQueryService; public String getOrGenerateInviteLink(Long calendarId) { Optional inviteLink = @@ -74,6 +78,23 @@ public InviteLink searchInviteInfo(String inviteCode) { new String(Base64.getUrlDecoder().decode(inviteCode))); } + @Transactional(readOnly = true) + public List searchFollowingsNotInvited(Long calendarId, String personalId) { + List calendarMembers = + calendarMemberService.searchCalendarMembers(calendarId); + return memberQueryService.searchFollowings(personalId).stream() + .filter( + follow -> { + for (var calendarMember : calendarMembers) { + if (calendarMember.memberId().equals(follow.getId())) { + return false; + } + } + return true; + }) + .toList(); + } + public void inviteMember(Long calendarId, Long invitedMemberId, Member inviter) { Calendar calendar = calendarQueryService.searchByCalendarId(calendarId); calendar.validateAuthenticatedMember(inviter.getId()); diff --git a/src/main/java/com/sillim/recordit/member/controller/MemberController.java b/src/main/java/com/sillim/recordit/member/controller/MemberController.java index ac0e48c3..f694d96d 100644 --- a/src/main/java/com/sillim/recordit/member/controller/MemberController.java +++ b/src/main/java/com/sillim/recordit/member/controller/MemberController.java @@ -71,14 +71,6 @@ public ResponseEntity> recommendMemberList( return ResponseEntity.ok(body); } - @GetMapping("/me/followings") - public ResponseEntity> myFollowingList(@CurrentMember Member member) { - return ResponseEntity.ok( - memberQueryService.searchFollowings(member.getPersonalId()).stream() - .map(MemberListResponse::of) - .toList()); - } - @PostMapping("/{memberId}/follow") public ResponseEntity follow(@PathVariable Long memberId, @CurrentMember Member member) throws IOException { diff --git a/src/test/java/com/sillim/recordit/invite/service/InviteServiceTest.java b/src/test/java/com/sillim/recordit/invite/service/InviteServiceTest.java index ecd380f6..b0b1ed6a 100644 --- a/src/test/java/com/sillim/recordit/invite/service/InviteServiceTest.java +++ b/src/test/java/com/sillim/recordit/invite/service/InviteServiceTest.java @@ -10,6 +10,7 @@ import com.sillim.recordit.calendar.domain.Calendar; import com.sillim.recordit.calendar.domain.CalendarCategory; +import com.sillim.recordit.calendar.dto.response.CalendarMemberResponse; import com.sillim.recordit.calendar.fixture.CalendarCategoryFixture; import com.sillim.recordit.calendar.fixture.CalendarFixture; import com.sillim.recordit.calendar.service.CalendarMemberService; @@ -23,9 +24,11 @@ import com.sillim.recordit.invite.repository.InviteLogRepository; import com.sillim.recordit.member.domain.Member; import com.sillim.recordit.member.fixture.MemberFixture; +import com.sillim.recordit.member.service.MemberQueryService; import com.sillim.recordit.pushalarm.service.AlarmService; import java.time.LocalDateTime; import java.util.Base64; +import java.util.List; import java.util.Optional; import java.util.UUID; import org.junit.jupiter.api.DisplayName; @@ -43,6 +46,7 @@ class InviteServiceTest { @Mock InviteLogRepository inviteLogRepository; @Mock CalendarMemberService calendarMemberService; @Mock AlarmService alarmService; + @Mock MemberQueryService memberQueryService; @InjectMocks InviteService inviteService; @DisplayName("유효한 초대 코드가 있다면 가져온다.") @@ -170,4 +174,23 @@ void throwInvalidRequestExceptionIfNotInvitedMemberWhenRejectInvitation() { .isInstanceOf(InvalidRequestException.class) .hasMessage(ErrorCode.INVALID_REQUEST.getDescription()); } + + @Test + @DisplayName("초대하지 않은 팔로우 목록을 가져온다.") + void searchFollowingsNotInvited() { + long calendarId = 1L; + long memberId = 1L; + String personalId = "test"; + CalendarMemberResponse calendarMember = new CalendarMemberResponse(1L, 2L, "name", "url"); + Member member = mock(Member.class); + given(calendarMemberService.searchCalendarMembers(eq(calendarId))) + .willReturn(List.of(calendarMember)); + given(memberQueryService.searchFollowings(eq(personalId))).willReturn(List.of(member)); + given(member.getId()).willReturn(memberId); + + List followings = inviteService.searchFollowingsNotInvited(calendarId, personalId); + + assertThat(followings).hasSize(1); + assertThat(followings.get(0).getId()).isEqualTo(1L); + } }