From 101444ee52e3cdfc8ca34ba0f975f73558f48451 Mon Sep 17 00:00:00 2001 From: 5nam Date: Fri, 11 Apr 2025 20:49:37 +0900 Subject: [PATCH 1/4] =?UTF-8?q?refactor(#29):=20saveNotice=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=EC=97=90=20=EA=B6=8C=ED=95=9C=20=ED=99=95=EC=9D=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../club/controller/NoticeController.java | 17 +++++------ .../club/controller/NoticeControllerDocs.java | 6 ++-- .../{request => response}/NoticeOutput.java | 2 +- .../club/service/NoticeCommandService.java | 4 ++- .../service/NoticeCommandServiceImpl.java | 29 ++++++++++++------- .../moim/club/service/NoticeQueryService.java | 5 ++-- .../club/service/NoticeQueryServiceImpl.java | 16 ++++++++-- .../service/NoticeCommandServiceImplTest.java | 28 ++++++++++++++++-- .../service/NoticeQueryServiceImplTest.java | 28 ++++++++++++++++-- 9 files changed, 98 insertions(+), 37 deletions(-) rename src/main/java/com/example/moim/club/dto/{request => response}/NoticeOutput.java (92%) diff --git a/src/main/java/com/example/moim/club/controller/NoticeController.java b/src/main/java/com/example/moim/club/controller/NoticeController.java index 23587ab..012e41f 100644 --- a/src/main/java/com/example/moim/club/controller/NoticeController.java +++ b/src/main/java/com/example/moim/club/controller/NoticeController.java @@ -1,9 +1,8 @@ package com.example.moim.club.controller; import com.example.moim.club.dto.request.NoticeInput; -import com.example.moim.club.dto.request.NoticeOutput; +import com.example.moim.club.dto.response.NoticeOutput; import com.example.moim.club.service.NoticeCommandService; -import com.example.moim.club.service.NoticeCommandServiceImpl; import com.example.moim.club.service.NoticeQueryService; import com.example.moim.global.exception.BaseResponse; import com.example.moim.global.exception.ResponseCode; @@ -15,6 +14,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; +import java.net.URI; import java.util.List; @RestController @@ -23,13 +23,10 @@ public class NoticeController implements NoticeControllerDocs { private final NoticeCommandService noticeCommandService; private final NoticeQueryService noticeQueryService; - /** - * FIXME: 응답 값이 무조건 있어야 함. user 의 권한 체크는 안해도 되나? - */ @PostMapping("/notice") - public BaseResponse noticeSave(NoticeInput noticeInput, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl) { - noticeCommandService.saveNotice(noticeInput); - return BaseResponse.onSuccess(null, ResponseCode.OK); + public BaseResponse saveNotice(@AuthenticationPrincipal UserDetailsImpl userDetailsImpl, NoticeInput noticeInput) { + NoticeOutput noticeOutput = noticeCommandService.saveNotice(userDetailsImpl.getUser(), noticeInput); + return BaseResponse.onSuccess(noticeOutput, ResponseCode.OK); } /** @@ -37,7 +34,7 @@ public BaseResponse noticeSave(NoticeInput noticeInput, @AuthenticationPrincipal * @return */ @GetMapping("/notice/{clubId}") - public BaseResponse> noticeSave(@PathVariable Long clubId, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl) { - return BaseResponse.onSuccess(noticeQueryService.findNotice(clubId), ResponseCode.OK); + public BaseResponse> findNotices(@PathVariable Long clubId, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl) { + return BaseResponse.onSuccess(noticeQueryService.findNotice(userDetailsImpl.getUser(), clubId), ResponseCode.OK); } } diff --git a/src/main/java/com/example/moim/club/controller/NoticeControllerDocs.java b/src/main/java/com/example/moim/club/controller/NoticeControllerDocs.java index eb7a706..9d6cb81 100644 --- a/src/main/java/com/example/moim/club/controller/NoticeControllerDocs.java +++ b/src/main/java/com/example/moim/club/controller/NoticeControllerDocs.java @@ -1,7 +1,7 @@ package com.example.moim.club.controller; import com.example.moim.club.dto.request.NoticeInput; -import com.example.moim.club.dto.request.NoticeOutput; +import com.example.moim.club.dto.response.NoticeOutput; import com.example.moim.global.exception.BaseResponse; import com.example.moim.user.dto.UserDetailsImpl; import io.swagger.v3.oas.annotations.Operation; @@ -14,8 +14,8 @@ @Tag(name = "모임 공지 api", description = "모임(club) 공지 api 분리") public interface NoticeControllerDocs { @Operation(summary = "공지 생성") - BaseResponse noticeSave(NoticeInput noticeInput, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl); + BaseResponse saveNotice(@AuthenticationPrincipal UserDetailsImpl userDetailsImpl, NoticeInput noticeInput); @Operation(summary = "공지 조회") - BaseResponse> noticeSave(@PathVariable Long clubId, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl); + BaseResponse> findNotices(@PathVariable Long clubId, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl); } diff --git a/src/main/java/com/example/moim/club/dto/request/NoticeOutput.java b/src/main/java/com/example/moim/club/dto/response/NoticeOutput.java similarity index 92% rename from src/main/java/com/example/moim/club/dto/request/NoticeOutput.java rename to src/main/java/com/example/moim/club/dto/response/NoticeOutput.java index 5e4267e..3633b87 100644 --- a/src/main/java/com/example/moim/club/dto/request/NoticeOutput.java +++ b/src/main/java/com/example/moim/club/dto/response/NoticeOutput.java @@ -1,4 +1,4 @@ -package com.example.moim.club.dto.request; +package com.example.moim.club.dto.response; import com.example.moim.club.entity.Notice; import lombok.Data; diff --git a/src/main/java/com/example/moim/club/service/NoticeCommandService.java b/src/main/java/com/example/moim/club/service/NoticeCommandService.java index 4d42d48..c6eb319 100644 --- a/src/main/java/com/example/moim/club/service/NoticeCommandService.java +++ b/src/main/java/com/example/moim/club/service/NoticeCommandService.java @@ -1,7 +1,9 @@ package com.example.moim.club.service; import com.example.moim.club.dto.request.NoticeInput; +import com.example.moim.club.dto.response.NoticeOutput; +import com.example.moim.user.entity.User; public interface NoticeCommandService { - void saveNotice(NoticeInput noticeInput); + NoticeOutput saveNotice(User user, NoticeInput noticeInput); } diff --git a/src/main/java/com/example/moim/club/service/NoticeCommandServiceImpl.java b/src/main/java/com/example/moim/club/service/NoticeCommandServiceImpl.java index 8423415..2b25ded 100644 --- a/src/main/java/com/example/moim/club/service/NoticeCommandServiceImpl.java +++ b/src/main/java/com/example/moim/club/service/NoticeCommandServiceImpl.java @@ -1,32 +1,39 @@ package com.example.moim.club.service; import com.example.moim.club.dto.request.NoticeInput; -import com.example.moim.club.dto.request.NoticeOutput; +import com.example.moim.club.dto.response.NoticeOutput; +import com.example.moim.club.entity.Club; import com.example.moim.club.entity.Notice; +import com.example.moim.club.entity.UserClub; import com.example.moim.club.exception.advice.ClubControllerAdvice; import com.example.moim.club.repository.ClubRepository; import com.example.moim.club.repository.NoticeRepository; +import com.example.moim.club.repository.UserClubRepository; +import com.example.moim.global.enums.ClubRole; import com.example.moim.global.exception.ResponseCode; +import com.example.moim.user.entity.User; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.util.List; - @Slf4j @Service @RequiredArgsConstructor public class NoticeCommandServiceImpl implements NoticeCommandService { private final NoticeRepository noticeRepository; private final ClubRepository clubRepository; + private final UserClubRepository userClubRepository; + + public NoticeOutput saveNotice(User user, NoticeInput noticeInput) { + Club club = clubRepository.findById(noticeInput.getClubId()).orElseThrow(() -> new ClubControllerAdvice(ResponseCode.CLUB_NOT_FOUND)); + UserClub userClub = userClubRepository.findByClubAndUser(club, user).orElseThrow(() -> new ClubControllerAdvice(ResponseCode.CLUB_USER_NOT_FOUND)); + + if (!userClub.getClubRole().equals(ClubRole.STAFF)) { // 공지 등록 권한 확인 + throw new ClubControllerAdvice(ResponseCode.CLUB_PERMISSION_DENIED); + } + + Notice notice = noticeRepository.save(Notice.createNotice(club, noticeInput.getTitle(), noticeInput.getContent())); - /** - * transaction 필요하지 않음. save 작업 하나만 이루어지고, 나머지는 다 조회 연산이므로 - * save 함수 내부에 이미 transaction 적용되어 있음 - * @param noticeInput - */ - public void saveNotice(NoticeInput noticeInput) { - noticeRepository.save(Notice.createNotice(clubRepository.findById(noticeInput.getClubId()).orElseThrow(() -> new ClubControllerAdvice(ResponseCode.CLUB_NOT_FOUND)), - noticeInput.getTitle(), noticeInput.getContent())); + return new NoticeOutput(notice); } } diff --git a/src/main/java/com/example/moim/club/service/NoticeQueryService.java b/src/main/java/com/example/moim/club/service/NoticeQueryService.java index 214db10..6be9091 100644 --- a/src/main/java/com/example/moim/club/service/NoticeQueryService.java +++ b/src/main/java/com/example/moim/club/service/NoticeQueryService.java @@ -1,9 +1,10 @@ package com.example.moim.club.service; -import com.example.moim.club.dto.request.NoticeOutput; +import com.example.moim.club.dto.response.NoticeOutput; +import com.example.moim.user.entity.User; import java.util.List; public interface NoticeQueryService { - List findNotice(Long clubId); + List findNotice(User user, Long clubId); } diff --git a/src/main/java/com/example/moim/club/service/NoticeQueryServiceImpl.java b/src/main/java/com/example/moim/club/service/NoticeQueryServiceImpl.java index 02ce284..d6560c2 100644 --- a/src/main/java/com/example/moim/club/service/NoticeQueryServiceImpl.java +++ b/src/main/java/com/example/moim/club/service/NoticeQueryServiceImpl.java @@ -1,10 +1,14 @@ package com.example.moim.club.service; -import com.example.moim.club.dto.request.NoticeOutput; +import com.example.moim.club.dto.response.NoticeOutput; +import com.example.moim.club.entity.Club; +import com.example.moim.club.entity.UserClub; import com.example.moim.club.exception.advice.ClubControllerAdvice; import com.example.moim.club.repository.ClubRepository; import com.example.moim.club.repository.NoticeRepository; +import com.example.moim.club.repository.UserClubRepository; import com.example.moim.global.exception.ResponseCode; +import com.example.moim.user.entity.User; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -16,8 +20,14 @@ public class NoticeQueryServiceImpl implements NoticeQueryService { private final NoticeRepository noticeRepository; private final ClubRepository clubRepository; + private final UserClubRepository userClubRepository; - public List findNotice(Long clubId) { - return noticeRepository.findByClub(clubRepository.findById(clubId).orElseThrow(() -> new ClubControllerAdvice(ResponseCode.CLUB_NOT_FOUND))).stream().map(NoticeOutput::new).toList(); + public List findNotice(User user, Long clubId) { + // 가입된 회원인지 확인 + Club club = clubRepository.findById(clubId).orElseThrow(() -> new ClubControllerAdvice(ResponseCode.CLUB_NOT_FOUND)); + UserClub userClub = userClubRepository.findByClubAndUser(club, user).orElseThrow(() -> new ClubControllerAdvice(ResponseCode.CLUB_USER_NOT_FOUND)); + + // 공지 조회 기준에 따라..(음 유저별로 여러 클럽들의 공지들을 다 조회하는 건가?) + return noticeRepository.findByClub(club).stream().map(NoticeOutput::new).toList(); } } diff --git a/src/test/java/com/example/moim/club/service/NoticeCommandServiceImplTest.java b/src/test/java/com/example/moim/club/service/NoticeCommandServiceImplTest.java index 2fc715f..038b95e 100644 --- a/src/test/java/com/example/moim/club/service/NoticeCommandServiceImplTest.java +++ b/src/test/java/com/example/moim/club/service/NoticeCommandServiceImplTest.java @@ -2,11 +2,13 @@ import com.example.moim.club.dto.request.ClubInput; import com.example.moim.club.dto.request.NoticeInput; -import com.example.moim.club.dto.request.NoticeOutput; import com.example.moim.club.entity.*; import com.example.moim.club.repository.ClubRepository; import com.example.moim.club.repository.NoticeRepository; +import com.example.moim.club.repository.UserClubRepository; import com.example.moim.global.enums.*; +import com.example.moim.user.dto.SignupInput; +import com.example.moim.user.entity.User; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -15,9 +17,10 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.util.ReflectionTestUtils; import org.springframework.web.multipart.MultipartFile; -import java.util.List; +import java.time.LocalDateTime; import java.util.Optional; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; @@ -31,11 +34,15 @@ class NoticeCommandServiceImplTest { private NoticeRepository noticeRepository; @Mock private ClubRepository clubRepository; + @Mock + private UserClubRepository userClubRepository; @InjectMocks private NoticeCommandServiceImpl noticeCommandServiceImpl; private ClubInput clubInput; private NoticeInput noticeInput; + private SignupInput signupInput; + @BeforeEach void init() { // Club @@ -59,6 +66,16 @@ void init() { // Notice this.noticeInput = NoticeInput.builder().title("notice title").content("notice content").clubId(1L).build(); + + // User + this.signupInput = SignupInput.builder() + .email("email") + .phone("phone") + .birthday("2000-08-28") + .name("name") + .password("password") + .gender(Gender.WOMAN.getKoreanName()) + .build(); } @Test @DisplayName("공지를 저장할 수 있다") @@ -66,10 +83,15 @@ void saveNotice() { //given Club club = Club.createClub(clubInput, null); Notice notice = Notice.createNotice(club, noticeInput.getTitle(), noticeInput.getContent()); + // notice - createAt 강제로 주입하기 + ReflectionTestUtils.setField(notice, "createdDate", LocalDateTime.now()); + User user = User.createUser(signupInput); + UserClub userClub = UserClub.createLeaderUserClub(user, club); //when when(noticeRepository.save(any(Notice.class))).thenReturn(notice); when(clubRepository.findById(any(Long.class))).thenReturn(Optional.of(club)); - noticeCommandServiceImpl.saveNotice(noticeInput); + when(userClubRepository.findByClubAndUser(any(Club.class), any(User.class))).thenReturn(Optional.of(userClub)); + noticeCommandServiceImpl.saveNotice(user, noticeInput); //then verify(noticeRepository, times(1)).save(any(Notice.class)); verify(clubRepository, times(1)).findById(any(Long.class)); diff --git a/src/test/java/com/example/moim/club/service/NoticeQueryServiceImplTest.java b/src/test/java/com/example/moim/club/service/NoticeQueryServiceImplTest.java index 68cce48..ed4f510 100644 --- a/src/test/java/com/example/moim/club/service/NoticeQueryServiceImplTest.java +++ b/src/test/java/com/example/moim/club/service/NoticeQueryServiceImplTest.java @@ -2,11 +2,14 @@ import com.example.moim.club.dto.request.ClubInput; import com.example.moim.club.dto.request.NoticeInput; -import com.example.moim.club.dto.request.NoticeOutput; +import com.example.moim.club.dto.response.NoticeOutput; import com.example.moim.club.entity.*; import com.example.moim.club.repository.ClubRepository; import com.example.moim.club.repository.NoticeRepository; +import com.example.moim.club.repository.UserClubRepository; import com.example.moim.global.enums.*; +import com.example.moim.user.dto.SignupInput; +import com.example.moim.user.entity.User; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -31,11 +34,14 @@ public class NoticeQueryServiceImplTest { private NoticeRepository noticeRepository; @Mock private ClubRepository clubRepository; + @Mock + private UserClubRepository userClubRepository; @InjectMocks private NoticeQueryServiceImpl noticeQueryService; private ClubInput clubInput; private NoticeInput noticeInput; + private SignupInput signupInput; @BeforeEach void init() { @@ -60,6 +66,16 @@ void init() { // Notice this.noticeInput = NoticeInput.builder().title("notice title").content("notice content").clubId(1L).build(); + + // User + this.signupInput = SignupInput.builder() + .email("email") + .phone("phone") + .birthday("2000-08-28") + .name("name") + .password("password") + .gender(Gender.WOMAN.getKoreanName()) + .build(); } @Test @@ -68,12 +84,15 @@ void findNotice() { //given Club club = Club.createClub(clubInput, null); Notice notice = Notice.createNotice(club, noticeInput.getTitle(), noticeInput.getContent()); + User user = User.createUser(signupInput); + UserClub userClub = UserClub.createUserClub(user, club); notice.setCreatedDate(); notice.setUpdatedDate(); //when when(clubRepository.findById(any(Long.class))).thenReturn(Optional.of(club)); when(noticeRepository.findByClub(any(Club.class))).thenReturn(List.of(notice)); - List result = noticeQueryService.findNotice(1L); + when(userClubRepository.findByClubAndUser(any(Club.class), any(User.class))).thenReturn(Optional.of(userClub)); + List result = noticeQueryService.findNotice(user, 1L); //then assertThat(result.size()).isEqualTo(1); assertThat(result.get(0).getTitle()).isEqualTo(noticeInput.getTitle()); @@ -87,11 +106,14 @@ void findNotice() { void findNotice_zero_notice() { //given Club club = Club.createClub(clubInput, null); + User user = User.createUser(signupInput); + UserClub userClub = UserClub.createUserClub(user, club); //when when(clubRepository.findById(any(Long.class))).thenReturn(Optional.of(club)); when(noticeRepository.findByClub(any(Club.class))).thenReturn(List.of()); - List result = noticeQueryService.findNotice(1L); + when(userClubRepository.findByClubAndUser(any(Club.class), any(User.class))).thenReturn(Optional.of(userClub)); + List result = noticeQueryService.findNotice(user, 1L); //then assertThat(result.size()).isEqualTo(0); verify(clubRepository, times(1)).findById(any(Long.class)); From 8c72589212b050ecaad8d71eadf262f247275f56 Mon Sep 17 00:00:00 2001 From: 5nam Date: Fri, 11 Apr 2025 22:55:07 +0900 Subject: [PATCH 2/4] =?UTF-8?q?refactor(#29):=20findNotices=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=95=20=EB=B0=A9=EC=8B=9D[cursor=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D]=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20=EB=82=98?= =?UTF-8?q?=EC=A4=91=EC=97=90=20=EC=83=9D=EC=84=B1=EB=90=9C=20=EC=88=9C?= =?UTF-8?q?=EC=84=9C=EB=8C=80=EB=A1=9C=20=EC=A0=95=EB=A0=AC=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9.=20=EA=B7=B8=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=EB=8F=84=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../club/controller/NoticeController.java | 16 ++--- .../club/controller/NoticeControllerDocs.java | 5 +- .../club/repository/NoticeRepository.java | 7 ++- .../repository/NoticeRepositoryCustom.java | 11 ++++ .../club/repository/NoticeRepositoryImpl.java | 38 +++++++++++ .../moim/club/service/NoticeQueryService.java | 3 +- .../club/service/NoticeQueryServiceImpl.java | 24 +++++-- .../service/NoticeQueryServiceImplTest.java | 63 ++++++++++++++++--- 8 files changed, 137 insertions(+), 30 deletions(-) create mode 100644 src/main/java/com/example/moim/club/repository/NoticeRepositoryCustom.java create mode 100644 src/main/java/com/example/moim/club/repository/NoticeRepositoryImpl.java diff --git a/src/main/java/com/example/moim/club/controller/NoticeController.java b/src/main/java/com/example/moim/club/controller/NoticeController.java index 012e41f..616731c 100644 --- a/src/main/java/com/example/moim/club/controller/NoticeController.java +++ b/src/main/java/com/example/moim/club/controller/NoticeController.java @@ -8,14 +8,10 @@ import com.example.moim.global.exception.ResponseCode; import com.example.moim.user.dto.UserDetailsImpl; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Slice; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; -import java.net.URI; -import java.util.List; @RestController @RequiredArgsConstructor @@ -29,12 +25,8 @@ public BaseResponse saveNotice(@AuthenticationPrincipal UserDetail return BaseResponse.onSuccess(noticeOutput, ResponseCode.OK); } - /** - * FIXME: 공지를 시간 순으로 정렬하지 않아도 되나? - * @return - */ @GetMapping("/notice/{clubId}") - public BaseResponse> findNotices(@PathVariable Long clubId, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl) { - return BaseResponse.onSuccess(noticeQueryService.findNotice(userDetailsImpl.getUser(), clubId), ResponseCode.OK); + public BaseResponse> findNotices(@PathVariable Long clubId, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl, @RequestParam("cursorId") Long cursorId) { + return BaseResponse.onSuccess(noticeQueryService.findNotice(userDetailsImpl.getUser(), clubId, cursorId), ResponseCode.OK); } } diff --git a/src/main/java/com/example/moim/club/controller/NoticeControllerDocs.java b/src/main/java/com/example/moim/club/controller/NoticeControllerDocs.java index 9d6cb81..17fe83e 100644 --- a/src/main/java/com/example/moim/club/controller/NoticeControllerDocs.java +++ b/src/main/java/com/example/moim/club/controller/NoticeControllerDocs.java @@ -6,8 +6,11 @@ import com.example.moim.user.dto.UserDetailsImpl; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; import java.util.List; @@ -17,5 +20,5 @@ public interface NoticeControllerDocs { BaseResponse saveNotice(@AuthenticationPrincipal UserDetailsImpl userDetailsImpl, NoticeInput noticeInput); @Operation(summary = "공지 조회") - BaseResponse> findNotices(@PathVariable Long clubId, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl); + BaseResponse> findNotices(@PathVariable Long clubId, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl, @RequestParam Long cursorId); } diff --git a/src/main/java/com/example/moim/club/repository/NoticeRepository.java b/src/main/java/com/example/moim/club/repository/NoticeRepository.java index b2547ad..0d38aaa 100644 --- a/src/main/java/com/example/moim/club/repository/NoticeRepository.java +++ b/src/main/java/com/example/moim/club/repository/NoticeRepository.java @@ -2,10 +2,13 @@ import com.example.moim.club.entity.Club; import com.example.moim.club.entity.Notice; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; -public interface NoticeRepository extends JpaRepository { - List findByClub(Club club); +public interface NoticeRepository extends JpaRepository, NoticeRepositoryCustom { +// Page findByClub(Club club, Pageable pageable); + } diff --git a/src/main/java/com/example/moim/club/repository/NoticeRepositoryCustom.java b/src/main/java/com/example/moim/club/repository/NoticeRepositoryCustom.java new file mode 100644 index 0000000..fb80b4a --- /dev/null +++ b/src/main/java/com/example/moim/club/repository/NoticeRepositoryCustom.java @@ -0,0 +1,11 @@ +package com.example.moim.club.repository; + +import com.example.moim.club.entity.Club; +import com.example.moim.club.entity.Notice; + +import java.util.List; + +public interface NoticeRepositoryCustom { + List findByCursor(Long cursor, int size, Club club); +} + diff --git a/src/main/java/com/example/moim/club/repository/NoticeRepositoryImpl.java b/src/main/java/com/example/moim/club/repository/NoticeRepositoryImpl.java new file mode 100644 index 0000000..e7fc92e --- /dev/null +++ b/src/main/java/com/example/moim/club/repository/NoticeRepositoryImpl.java @@ -0,0 +1,38 @@ +package com.example.moim.club.repository; + +import com.example.moim.club.entity.Club; +import com.example.moim.club.entity.Notice; +import com.example.moim.club.entity.QNotice; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +@RequiredArgsConstructor +public class NoticeRepositoryImpl implements NoticeRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + @Override + public List findByCursor(Long cursor, int size, Club club) { + return queryFactory + .selectFrom(QNotice.notice) + .where( + ltCursor(cursor), + clubEq(club) + ) + .orderBy(QNotice.notice.id.desc()) + .limit(size + 1) // hasNext 판단용으로 1개 더 + .fetch(); + } + + private BooleanExpression ltCursor(Long cursor) { + return cursor != null ? QNotice.notice.id.lt(cursor) : null; + } + + private BooleanExpression clubEq(Club club) { + return club != null ? QNotice.notice.club.eq(club) : null; + } +} + diff --git a/src/main/java/com/example/moim/club/service/NoticeQueryService.java b/src/main/java/com/example/moim/club/service/NoticeQueryService.java index 6be9091..a763238 100644 --- a/src/main/java/com/example/moim/club/service/NoticeQueryService.java +++ b/src/main/java/com/example/moim/club/service/NoticeQueryService.java @@ -2,9 +2,10 @@ import com.example.moim.club.dto.response.NoticeOutput; import com.example.moim.user.entity.User; +import org.springframework.data.domain.Slice; import java.util.List; public interface NoticeQueryService { - List findNotice(User user, Long clubId); + Slice findNotice(User user, Long clubId, Long cursorId); } diff --git a/src/main/java/com/example/moim/club/service/NoticeQueryServiceImpl.java b/src/main/java/com/example/moim/club/service/NoticeQueryServiceImpl.java index d6560c2..719afd4 100644 --- a/src/main/java/com/example/moim/club/service/NoticeQueryServiceImpl.java +++ b/src/main/java/com/example/moim/club/service/NoticeQueryServiceImpl.java @@ -2,14 +2,17 @@ import com.example.moim.club.dto.response.NoticeOutput; import com.example.moim.club.entity.Club; +import com.example.moim.club.entity.Notice; import com.example.moim.club.entity.UserClub; import com.example.moim.club.exception.advice.ClubControllerAdvice; import com.example.moim.club.repository.ClubRepository; import com.example.moim.club.repository.NoticeRepository; import com.example.moim.club.repository.UserClubRepository; +import com.example.moim.global.enums.ClubRole; import com.example.moim.global.exception.ResponseCode; import com.example.moim.user.entity.User; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.*; import org.springframework.stereotype.Service; import java.util.List; @@ -18,16 +21,29 @@ @RequiredArgsConstructor public class NoticeQueryServiceImpl implements NoticeQueryService { + private static final int SIZE = 20; + private final NoticeRepository noticeRepository; private final ClubRepository clubRepository; private final UserClubRepository userClubRepository; - public List findNotice(User user, Long clubId) { - // 가입된 회원인지 확인 + public Slice findNotice(User user, Long clubId, Long cursorId) { + // 가입된 회원인지 확인, 가입되지 않은 회원이면 공지 열람 권한이 없는 것 Club club = clubRepository.findById(clubId).orElseThrow(() -> new ClubControllerAdvice(ResponseCode.CLUB_NOT_FOUND)); UserClub userClub = userClubRepository.findByClubAndUser(club, user).orElseThrow(() -> new ClubControllerAdvice(ResponseCode.CLUB_USER_NOT_FOUND)); - // 공지 조회 기준에 따라..(음 유저별로 여러 클럽들의 공지들을 다 조회하는 건가?) - return noticeRepository.findByClub(club).stream().map(NoticeOutput::new).toList(); + List notices = noticeRepository.findByCursor(cursorId, SIZE, club); + + boolean hasNext = notices.size() > SIZE; + + if (hasNext) { + notices.remove(SIZE); + } + + List outputs = notices.stream() + .map(NoticeOutput::new) + .toList(); + + return new SliceImpl<>(outputs, PageRequest.of(0, SIZE), hasNext); } } diff --git a/src/test/java/com/example/moim/club/service/NoticeQueryServiceImplTest.java b/src/test/java/com/example/moim/club/service/NoticeQueryServiceImplTest.java index ed4f510..7d1bf49 100644 --- a/src/test/java/com/example/moim/club/service/NoticeQueryServiceImplTest.java +++ b/src/test/java/com/example/moim/club/service/NoticeQueryServiceImplTest.java @@ -10,6 +10,7 @@ import com.example.moim.global.enums.*; import com.example.moim.user.dto.SignupInput; import com.example.moim.user.entity.User; +import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -17,9 +18,13 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Slice; import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.util.ReflectionTestUtils; import org.springframework.web.multipart.MultipartFile; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; import java.util.Optional; @@ -28,6 +33,7 @@ import static org.mockito.Mockito.*; import static org.mockito.Mockito.times; +@Slf4j @ExtendWith(MockitoExtension.class) public class NoticeQueryServiceImplTest { @Mock @@ -90,15 +96,17 @@ void findNotice() { notice.setUpdatedDate(); //when when(clubRepository.findById(any(Long.class))).thenReturn(Optional.of(club)); - when(noticeRepository.findByClub(any(Club.class))).thenReturn(List.of(notice)); + when(noticeRepository.findByCursor(any(Long.class), any(Integer.class), any(Club.class))).thenReturn(List.of(notice)); when(userClubRepository.findByClubAndUser(any(Club.class), any(User.class))).thenReturn(Optional.of(userClub)); - List result = noticeQueryService.findNotice(user, 1L); + Slice result = noticeQueryService.findNotice(user, 1L, 0L); + //then - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getTitle()).isEqualTo(noticeInput.getTitle()); - assertThat(result.get(0).getContent()).isEqualTo(noticeInput.getContent()); + assertThat(result.getSize()).isEqualTo(20); + assertThat(result.getNumberOfElements()).isEqualTo(1); + assertThat(result.hasNext()).isFalse(); + assertThat(result.getContent().get(0).getTitle()).isEqualTo("notice title"); verify(clubRepository, times(1)).findById(any(Long.class)); - verify(noticeRepository, times(1)).findByClub(any(Club.class)); + verify(noticeRepository, times(1)).findByCursor(any(Long.class), any(Integer.class), any(Club.class)); } @Test @@ -111,12 +119,47 @@ void findNotice_zero_notice() { //when when(clubRepository.findById(any(Long.class))).thenReturn(Optional.of(club)); - when(noticeRepository.findByClub(any(Club.class))).thenReturn(List.of()); + when(noticeRepository.findByCursor(any(Long.class), any(Integer.class), any(Club.class))).thenReturn(List.of()); + when(userClubRepository.findByClubAndUser(any(Club.class), any(User.class))).thenReturn(Optional.of(userClub)); + Slice result = noticeQueryService.findNotice(user, 1L, 0L); + //then + assertThat(result.getSize()).isEqualTo(20); + assertThat(result.getNumberOfElements()).isEqualTo(0); + assertThat(result.hasNext()).isFalse(); + assertThat(result.hasContent()).isFalse(); + verify(clubRepository, times(1)).findById(any(Long.class)); + verify(noticeRepository, times(1)).findByCursor(any(Long.class), any(Integer.class), any(Club.class)); + } + + @Test + @DisplayName("동아리에 등록된 공지를 조회하면 나중에 저장된 순으로 정렬되어 있다.") + void findNotice_sort() { + //given + Club club = Club.createClub(clubInput, null); + Notice notice = Notice.createNotice(club, noticeInput.getTitle(), noticeInput.getContent()); + ReflectionTestUtils.setField(notice, "id", 1L); + LocalDateTime localDateTime = LocalDateTime.now(); + ReflectionTestUtils.setField(notice, "createdDate", localDateTime); + Notice notice2 = Notice.createNotice(club, noticeInput.getTitle(), noticeInput.getContent()); + ReflectionTestUtils.setField(notice2, "id", 2L); + LocalDateTime localDateTime2 = LocalDateTime.now(); + ReflectionTestUtils.setField(notice2, "createdDate", localDateTime2); + User user = User.createUser(signupInput); + UserClub userClub = UserClub.createUserClub(user, club); + + //when + when(clubRepository.findById(any(Long.class))).thenReturn(Optional.of(club)); + when(noticeRepository.findByCursor(any(Long.class), any(Integer.class), any(Club.class))).thenReturn(List.of(notice, notice2)); when(userClubRepository.findByClubAndUser(any(Club.class), any(User.class))).thenReturn(Optional.of(userClub)); - List result = noticeQueryService.findNotice(user, 1L); + Slice result = noticeQueryService.findNotice(user, 1L, 0L); + //then - assertThat(result.size()).isEqualTo(0); + assertThat(result.getSize()).isEqualTo(20); + assertThat(result.getNumberOfElements()).isEqualTo(2); + assertThat(result.hasNext()).isFalse(); + assertThat(result.getContent().get(0).getCreatedDate()).isEqualTo(LocalDate.from(localDateTime2)); + assertThat(result.getContent().get(1).getCreatedDate()).isEqualTo(LocalDate.from(localDateTime)); verify(clubRepository, times(1)).findById(any(Long.class)); - verify(noticeRepository, times(1)).findByClub(any(Club.class)); + verify(noticeRepository, times(1)).findByCursor(any(Long.class), any(Integer.class), any(Club.class)); } } From f91fc18d1cafd8d87ec5e079d0d529c2d068eab8 Mon Sep 17 00:00:00 2001 From: 5nam Date: Sat, 12 Apr 2025 13:31:47 +0900 Subject: [PATCH 3/4] =?UTF-8?q?refactor(#29):=20saveNotice=20clubId=20?= =?UTF-8?q?=EB=B0=9B=EC=95=84=EC=98=A4=EB=8A=94=20=EA=B2=83=20PathVariable?= =?UTF-8?q?=20=EB=B0=A9=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD,?= =?UTF-8?q?=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20=EC=9C=84=ED=95=9C=20csrf=20=EB=81=84?= =?UTF-8?q?=EA=B8=B0=20=EC=BD=94=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 --- deploy/local.init.sql | 10 ++++++++- .../club/controller/NoticeController.java | 21 +++++++++++++++---- .../club/controller/NoticeControllerDocs.java | 7 +++++-- .../moim/club/dto/request/NoticeInput.java | 4 +--- .../club/repository/ClubRepositoryImpl.java | 2 +- .../club/repository/NoticeRepositoryImpl.java | 6 +++++- .../club/service/NoticeCommandService.java | 2 +- .../service/NoticeCommandServiceImpl.java | 6 ++++-- .../moim/config/security/SecurityConfig.java | 2 ++ .../service/NoticeCommandServiceImplTest.java | 4 ++-- .../service/NoticeQueryServiceImplTest.java | 2 +- 11 files changed, 48 insertions(+), 18 deletions(-) diff --git a/deploy/local.init.sql b/deploy/local.init.sql index 8ac668a..eab3437 100644 --- a/deploy/local.init.sql +++ b/deploy/local.init.sql @@ -27,4 +27,12 @@ VALUES (default, null, null, 'STAFF', '2024-12-11', 2, 2, 1, 1); INSERT INTO user_club (id, created_date, updated_date, club_role, join_date, match_count, schedule_count, club_id, user_id) VALUES (default, null, null, 'STAFF', '2024-12-11', 2, 2, 3, 3); INSERT INTO user_club (id, created_date, updated_date, club_role, join_date, match_count, schedule_count, club_id, user_id) -VALUES (default, null, null, 'STAFF', '2024-12-11', 2, 2, 3, 4); \ No newline at end of file +VALUES (default, null, null, 'STAFF', '2024-12-11', 2, 2, 3, 4); + +-- notice +INSERT INTO notice (id, created_date, updated_date, club_id, title, content) +values (default, '2024-12-10', null, 1, 'title', 'content'); +INSERT INTO notice (id, created_date, updated_date, club_id, title, content) +values (default, '2024-12-11', null, 1, 'title2', 'content2'); +INSERT INTO notice (id, created_date, updated_date, club_id, title, content) +values (default, '2024-12-12', null, 1, 'title3', 'content4'); \ No newline at end of file diff --git a/src/main/java/com/example/moim/club/controller/NoticeController.java b/src/main/java/com/example/moim/club/controller/NoticeController.java index 616731c..54d5eab 100644 --- a/src/main/java/com/example/moim/club/controller/NoticeController.java +++ b/src/main/java/com/example/moim/club/controller/NoticeController.java @@ -7,6 +7,8 @@ import com.example.moim.global.exception.BaseResponse; import com.example.moim.global.exception.ResponseCode; import com.example.moim.user.dto.UserDetailsImpl; +import com.example.moim.user.entity.User; +import com.example.moim.user.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Slice; import org.springframework.security.core.annotation.AuthenticationPrincipal; @@ -18,15 +20,26 @@ public class NoticeController implements NoticeControllerDocs { private final NoticeCommandService noticeCommandService; private final NoticeQueryService noticeQueryService; + private final UserRepository userRepository; - @PostMapping("/notice") - public BaseResponse saveNotice(@AuthenticationPrincipal UserDetailsImpl userDetailsImpl, NoticeInput noticeInput) { - NoticeOutput noticeOutput = noticeCommandService.saveNotice(userDetailsImpl.getUser(), noticeInput); + @PostMapping("/notice/{clubId}") + public BaseResponse saveNotice(@AuthenticationPrincipal UserDetailsImpl userDetailsImpl, @ModelAttribute NoticeInput noticeInput, @PathVariable("clubId") Long clubId) { +// public BaseResponse saveNotice(@ModelAttribute NoticeInput noticeInput, @PathVariable("clubId") Long clubId) { + /** + * FIXME: 컨트롤러 테스트용 코드 + */ +// User user = userRepository.findById(3L).get(); + NoticeOutput noticeOutput = noticeCommandService.saveNotice(userDetailsImpl.getUser(), noticeInput, clubId); return BaseResponse.onSuccess(noticeOutput, ResponseCode.OK); } @GetMapping("/notice/{clubId}") - public BaseResponse> findNotices(@PathVariable Long clubId, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl, @RequestParam("cursorId") Long cursorId) { + public BaseResponse> findNotices(@PathVariable Long clubId, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl, @RequestParam("cursorId") Long cursorId) { +// public BaseResponse> findNotices(@PathVariable Long clubId, @RequestParam(value = "cursorId", required = false) Long cursorId) { + /** + * FIXME: 컨트롤러 테스트용 코드 + */ +// User user = userRepository.findById(1L).get(); return BaseResponse.onSuccess(noticeQueryService.findNotice(userDetailsImpl.getUser(), clubId, cursorId), ResponseCode.OK); } } diff --git a/src/main/java/com/example/moim/club/controller/NoticeControllerDocs.java b/src/main/java/com/example/moim/club/controller/NoticeControllerDocs.java index 17fe83e..cd0f5c6 100644 --- a/src/main/java/com/example/moim/club/controller/NoticeControllerDocs.java +++ b/src/main/java/com/example/moim/club/controller/NoticeControllerDocs.java @@ -9,6 +9,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; @@ -17,8 +18,10 @@ @Tag(name = "모임 공지 api", description = "모임(club) 공지 api 분리") public interface NoticeControllerDocs { @Operation(summary = "공지 생성") - BaseResponse saveNotice(@AuthenticationPrincipal UserDetailsImpl userDetailsImpl, NoticeInput noticeInput); + BaseResponse saveNotice(@AuthenticationPrincipal UserDetailsImpl userDetailsImpl, @ModelAttribute NoticeInput noticeInput, @PathVariable("clubId") Long clubId); +// BaseResponse saveNotice(@ModelAttribute NoticeInput noticeInput, @PathVariable Long clubId); - @Operation(summary = "공지 조회") + @Operation(summary = "공지 조회, 최초 요청 시 cursorId null 로 보내기") BaseResponse> findNotices(@PathVariable Long clubId, @AuthenticationPrincipal UserDetailsImpl userDetailsImpl, @RequestParam Long cursorId); +// BaseResponse> findNotices(@PathVariable Long clubId, @RequestParam Long cursorId); } diff --git a/src/main/java/com/example/moim/club/dto/request/NoticeInput.java b/src/main/java/com/example/moim/club/dto/request/NoticeInput.java index 64a8859..a9a27bd 100644 --- a/src/main/java/com/example/moim/club/dto/request/NoticeInput.java +++ b/src/main/java/com/example/moim/club/dto/request/NoticeInput.java @@ -7,13 +7,11 @@ @Data @NoArgsConstructor public class NoticeInput { - private Long clubId; private String title; private String content; @Builder - public NoticeInput(Long clubId, String title, String content) { - this.clubId = clubId; + public NoticeInput(String title, String content) { this.title = title; this.content = content; } diff --git a/src/main/java/com/example/moim/club/repository/ClubRepositoryImpl.java b/src/main/java/com/example/moim/club/repository/ClubRepositoryImpl.java index f9908d7..7fd19ac 100644 --- a/src/main/java/com/example/moim/club/repository/ClubRepositoryImpl.java +++ b/src/main/java/com/example/moim/club/repository/ClubRepositoryImpl.java @@ -18,7 +18,7 @@ import static com.example.moim.club.entity.QClubSearch.clubSearch; import static org.springframework.util.StringUtils.hasText; -public class ClubRepositoryImpl implements ClubRepositoryCustom{ +public class ClubRepositoryImpl implements ClubRepositoryCustom { private final JPAQueryFactory queryFactory; public ClubRepositoryImpl(EntityManager em) { diff --git a/src/main/java/com/example/moim/club/repository/NoticeRepositoryImpl.java b/src/main/java/com/example/moim/club/repository/NoticeRepositoryImpl.java index e7fc92e..94f9e79 100644 --- a/src/main/java/com/example/moim/club/repository/NoticeRepositoryImpl.java +++ b/src/main/java/com/example/moim/club/repository/NoticeRepositoryImpl.java @@ -5,15 +5,19 @@ import com.example.moim.club.entity.QNotice; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; import lombok.RequiredArgsConstructor; import java.util.List; -@RequiredArgsConstructor public class NoticeRepositoryImpl implements NoticeRepositoryCustom { private final JPAQueryFactory queryFactory; + public NoticeRepositoryImpl(EntityManager em) { + this.queryFactory = new JPAQueryFactory(em); + } + @Override public List findByCursor(Long cursor, int size, Club club) { return queryFactory diff --git a/src/main/java/com/example/moim/club/service/NoticeCommandService.java b/src/main/java/com/example/moim/club/service/NoticeCommandService.java index c6eb319..f6c3e0b 100644 --- a/src/main/java/com/example/moim/club/service/NoticeCommandService.java +++ b/src/main/java/com/example/moim/club/service/NoticeCommandService.java @@ -5,5 +5,5 @@ import com.example.moim.user.entity.User; public interface NoticeCommandService { - NoticeOutput saveNotice(User user, NoticeInput noticeInput); + NoticeOutput saveNotice(User user, NoticeInput noticeInput, Long clubId); } diff --git a/src/main/java/com/example/moim/club/service/NoticeCommandServiceImpl.java b/src/main/java/com/example/moim/club/service/NoticeCommandServiceImpl.java index 2b25ded..84ed02e 100644 --- a/src/main/java/com/example/moim/club/service/NoticeCommandServiceImpl.java +++ b/src/main/java/com/example/moim/club/service/NoticeCommandServiceImpl.java @@ -24,11 +24,13 @@ public class NoticeCommandServiceImpl implements NoticeCommandService { private final ClubRepository clubRepository; private final UserClubRepository userClubRepository; - public NoticeOutput saveNotice(User user, NoticeInput noticeInput) { - Club club = clubRepository.findById(noticeInput.getClubId()).orElseThrow(() -> new ClubControllerAdvice(ResponseCode.CLUB_NOT_FOUND)); + public NoticeOutput saveNotice(User user, NoticeInput noticeInput, Long clubId) { + log.debug("saveNotice 진입"); + Club club = clubRepository.findById(clubId).orElseThrow(() -> new ClubControllerAdvice(ResponseCode.CLUB_NOT_FOUND)); UserClub userClub = userClubRepository.findByClubAndUser(club, user).orElseThrow(() -> new ClubControllerAdvice(ResponseCode.CLUB_USER_NOT_FOUND)); if (!userClub.getClubRole().equals(ClubRole.STAFF)) { // 공지 등록 권한 확인 + log.debug("권한 오류"); throw new ClubControllerAdvice(ResponseCode.CLUB_PERMISSION_DENIED); } diff --git a/src/main/java/com/example/moim/config/security/SecurityConfig.java b/src/main/java/com/example/moim/config/security/SecurityConfig.java index 3705755..3fed711 100644 --- a/src/main/java/com/example/moim/config/security/SecurityConfig.java +++ b/src/main/java/com/example/moim/config/security/SecurityConfig.java @@ -71,6 +71,8 @@ public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { httpSecurity.csrf(csrf -> csrf .ignoringRequestMatchers("/club/**") ); + httpSecurity.csrf(csrf -> csrf.ignoringRequestMatchers("/notice/**")); + //From 로그인 방식 disable httpSecurity.formLogin(AbstractHttpConfigurer::disable); //http basic 인증 방식 disable diff --git a/src/test/java/com/example/moim/club/service/NoticeCommandServiceImplTest.java b/src/test/java/com/example/moim/club/service/NoticeCommandServiceImplTest.java index 038b95e..4547a71 100644 --- a/src/test/java/com/example/moim/club/service/NoticeCommandServiceImplTest.java +++ b/src/test/java/com/example/moim/club/service/NoticeCommandServiceImplTest.java @@ -65,7 +65,7 @@ void init() { .clubPassword(clubPassword).profileImg(profileImg).mainUniformColor(mainUniformColor).subUniformColor(subUniformColor).build(); // Notice - this.noticeInput = NoticeInput.builder().title("notice title").content("notice content").clubId(1L).build(); + this.noticeInput = NoticeInput.builder().title("notice title").content("notice content").build(); // User this.signupInput = SignupInput.builder() @@ -91,7 +91,7 @@ void saveNotice() { when(noticeRepository.save(any(Notice.class))).thenReturn(notice); when(clubRepository.findById(any(Long.class))).thenReturn(Optional.of(club)); when(userClubRepository.findByClubAndUser(any(Club.class), any(User.class))).thenReturn(Optional.of(userClub)); - noticeCommandServiceImpl.saveNotice(user, noticeInput); + noticeCommandServiceImpl.saveNotice(user, noticeInput, 1L); //then verify(noticeRepository, times(1)).save(any(Notice.class)); verify(clubRepository, times(1)).findById(any(Long.class)); diff --git a/src/test/java/com/example/moim/club/service/NoticeQueryServiceImplTest.java b/src/test/java/com/example/moim/club/service/NoticeQueryServiceImplTest.java index 7d1bf49..5b66afd 100644 --- a/src/test/java/com/example/moim/club/service/NoticeQueryServiceImplTest.java +++ b/src/test/java/com/example/moim/club/service/NoticeQueryServiceImplTest.java @@ -71,7 +71,7 @@ void init() { .clubPassword(clubPassword).profileImg(profileImg).mainUniformColor(mainUniformColor).subUniformColor(subUniformColor).build(); // Notice - this.noticeInput = NoticeInput.builder().title("notice title").content("notice content").clubId(1L).build(); + this.noticeInput = NoticeInput.builder().title("notice title").content("notice content").build(); // User this.signupInput = SignupInput.builder() From 0c3c9dfe616c24b1400f6fabc248ff8a517ce263 Mon Sep 17 00:00:00 2001 From: 5nam Date: Sat, 12 Apr 2025 14:44:17 +0900 Subject: [PATCH 4/4] =?UTF-8?q?refactor(#29):=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20TODO=20=EB=A1=9C=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/moim/club/service/ClubCommandServiceImpl.java | 3 +++ .../example/moim/club/service/NoticeCommandServiceImpl.java | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/main/java/com/example/moim/club/service/ClubCommandServiceImpl.java b/src/main/java/com/example/moim/club/service/ClubCommandServiceImpl.java index 7dadc51..88cbcc6 100644 --- a/src/main/java/com/example/moim/club/service/ClubCommandServiceImpl.java +++ b/src/main/java/com/example/moim/club/service/ClubCommandServiceImpl.java @@ -83,6 +83,9 @@ public UserClubOutput saveClubUser(User user, ClubUserSaveInput clubUserSaveInpu } club.plusMemberCount(); UserClub userClub = userClubRepository.save(UserClub.createUserClub(user, club)); + /** + * TODO: 알림 보내는 것 새로운 방식에 맞춰서 다시 구현해야 함 + */ eventPublisher.publishEvent(new ClubJoinEvent(user, club)); return new UserClubOutput(userClub); } diff --git a/src/main/java/com/example/moim/club/service/NoticeCommandServiceImpl.java b/src/main/java/com/example/moim/club/service/NoticeCommandServiceImpl.java index 84ed02e..b42a3f5 100644 --- a/src/main/java/com/example/moim/club/service/NoticeCommandServiceImpl.java +++ b/src/main/java/com/example/moim/club/service/NoticeCommandServiceImpl.java @@ -36,6 +36,10 @@ public NoticeOutput saveNotice(User user, NoticeInput noticeInput, Long clubId) Notice notice = noticeRepository.save(Notice.createNotice(club, noticeInput.getTitle(), noticeInput.getContent())); + /** + * TODO: 알림 보내는 부분 구현해야함 + */ + return new NoticeOutput(notice); } }