From 59769212468647679d27b4e91bd535af5a581132 Mon Sep 17 00:00:00 2001 From: hyeonjeongs Date: Fri, 26 Jan 2024 15:27:51 +0900 Subject: [PATCH 01/11] =?UTF-8?q?=EA=B3=B5=EC=A7=80=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notice/controller/NoticeController.java | 29 +++++++++++++++++ .../domain/notice/dto/NoticeDataResponse.java | 28 +++++++++++++++++ .../notice/repository/NoticeRepository.java | 6 ++++ .../repository/NoticeRepositoryImpl.java | 15 +++++++-- .../domain/notice/service/NoticeService.java | 31 +++++++++++++++++++ .../server/global/common/SuccessCode.java | 1 + .../global/common/factory/TimeFactory.java | 5 +++ 7 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/yello/server/domain/notice/controller/NoticeController.java create mode 100644 src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java create mode 100644 src/main/java/com/yello/server/domain/notice/service/NoticeService.java diff --git a/src/main/java/com/yello/server/domain/notice/controller/NoticeController.java b/src/main/java/com/yello/server/domain/notice/controller/NoticeController.java new file mode 100644 index 00000000..b632102b --- /dev/null +++ b/src/main/java/com/yello/server/domain/notice/controller/NoticeController.java @@ -0,0 +1,29 @@ +package com.yello.server.domain.notice.controller; + + +import com.yello.server.domain.notice.dto.NoticeDataResponse; +import com.yello.server.domain.notice.service.NoticeService; +import com.yello.server.domain.user.entity.User; +import com.yello.server.global.common.annotation.AccessTokenUser; +import com.yello.server.global.common.dto.BaseResponse; +import lombok.RequiredArgsConstructor; +import lombok.val; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static com.yello.server.global.common.SuccessCode.READ_NOTICE_SUCCESS; + +@RestController +@RequiredArgsConstructor +@RequestMapping("api/v1") +public class NoticeController { + + private final NoticeService noticeService; + + @GetMapping("/notice") + public BaseResponse findNotice(@AccessTokenUser User user) { + val data = noticeService.findNotice(user.getId()); + return BaseResponse.success(READ_NOTICE_SUCCESS, data); + } +} diff --git a/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java b/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java new file mode 100644 index 00000000..94180e49 --- /dev/null +++ b/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java @@ -0,0 +1,28 @@ +package com.yello.server.domain.notice.dto; + +import com.yello.server.domain.notice.entity.Notice; +import lombok.Builder; + +import java.time.LocalDateTime; + +import static com.yello.server.global.common.factory.TimeFactory.toYearAndMonthFormattedString; + +@Builder +public record NoticeDataResponse( + String imageUrl, + String redirectUrl, + String startDate, + String endDate, + boolean isAvailable +) { + public static NoticeDataResponse of(Notice notice, Boolean isAvailable) { + return NoticeDataResponse.builder() + .imageUrl(notice.getImageUrl()) + .redirectUrl(notice.getRedirectUrl()) + .startDate(toYearAndMonthFormattedString(notice.getCreatedAt())) + .endDate(toYearAndMonthFormattedString(notice.getEndDate().toLocalDateTime())) + .isAvailable(isAvailable) + .build(); + } + +} diff --git a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepository.java b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepository.java index c993de02..6d95c3f2 100644 --- a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepository.java +++ b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepository.java @@ -1,5 +1,11 @@ package com.yello.server.domain.notice.repository; +import com.yello.server.domain.notice.entity.Notice; + +import java.util.Optional; + public interface NoticeRepository { + Notice getTopNotice(); + } diff --git a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java index 8b3bc062..1bb69da9 100644 --- a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java +++ b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java @@ -2,11 +2,16 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import com.yello.server.domain.notice.entity.Notice; -import java.util.Optional; +import com.yello.server.domain.purchase.exception.PurchaseConflictException; +import com.yello.server.global.common.ErrorCode; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; + +import static com.yello.server.domain.notice.entity.QNotice.notice; + @Repository @RequiredArgsConstructor @Transactional(readOnly = true) @@ -15,5 +20,11 @@ public class NoticeRepositoryImpl implements NoticeRepository { private final NoticeJpaRepository noticeJpaRepository; private final JPAQueryFactory jpaQueryFactory; - + @Override + public Notice getTopNotice() { + return jpaQueryFactory + .selectFrom(notice) + .orderBy(notice.endDate.desc()) + .fetchFirst(); + } } diff --git a/src/main/java/com/yello/server/domain/notice/service/NoticeService.java b/src/main/java/com/yello/server/domain/notice/service/NoticeService.java new file mode 100644 index 00000000..d8764e73 --- /dev/null +++ b/src/main/java/com/yello/server/domain/notice/service/NoticeService.java @@ -0,0 +1,31 @@ +package com.yello.server.domain.notice.service; + +import com.yello.server.domain.notice.dto.NoticeDataResponse; +import com.yello.server.domain.notice.entity.Notice; +import com.yello.server.domain.notice.repository.NoticeRepository; +import com.yello.server.domain.user.entity.User; +import com.yello.server.domain.user.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.Optional; + +import static com.yello.server.global.common.factory.TimeFactory.compareNowAndEndData; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class NoticeService { + private final NoticeRepository noticeRepository; + private final UserRepository userRepository; + + public NoticeDataResponse findNotice(Long userId) { + final User user = userRepository.getById(userId); + Notice noticeData = noticeRepository.getTopNotice(); + return NoticeDataResponse.of(noticeData, compareNowAndEndData(noticeData.getEndDate())); + } + + +} diff --git a/src/main/java/com/yello/server/global/common/SuccessCode.java b/src/main/java/com/yello/server/global/common/SuccessCode.java index f7eb5d07..72c127d6 100644 --- a/src/main/java/com/yello/server/global/common/SuccessCode.java +++ b/src/main/java/com/yello/server/global/common/SuccessCode.java @@ -48,6 +48,7 @@ public enum SuccessCode { DELETE_QUESTION_ADMIN_SUCCESS(OK, "어드민 권환으로 질문지 삭제에 성공하였습니다."), CLASS_NAME_SEARCH_BY_SCHOOL_NAME_SCHOOL_SUCCESS(OK, "학반 검색에 성공했습니다."), READ_USER_SUBSCRIBE_SUCCESS(OK, "구독 정보 조회에 성공하였습니다."), + READ_NOTICE_SUCCESS(OK, "공지 조회에 성공하였습니다."), /** * 201 CREATED diff --git a/src/main/java/com/yello/server/global/common/factory/TimeFactory.java b/src/main/java/com/yello/server/global/common/factory/TimeFactory.java index 8086c42f..d54b1737 100644 --- a/src/main/java/com/yello/server/global/common/factory/TimeFactory.java +++ b/src/main/java/com/yello/server/global/common/factory/TimeFactory.java @@ -2,6 +2,7 @@ import java.time.Duration; import java.time.LocalDateTime; +import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; public class TimeFactory { @@ -61,5 +62,9 @@ public static String toYearAndMonthFormattedString(LocalDateTime localDateTime) return dateTimePlusSevenDays.format(dateTimeFormatter); } + public static Boolean compareNowAndEndData(ZonedDateTime localDateTime) { + ZonedDateTime now = ZonedDateTime.now(); + return now.isBefore(localDateTime); + } } From 8b6fd2f182405949c62518da87122027d7ec9a96 Mon Sep 17 00:00:00 2001 From: hyeonjeongs Date: Fri, 26 Jan 2024 15:30:41 +0900 Subject: [PATCH 02/11] localdate time fix --- .../com/yello/server/domain/notice/dto/NoticeDataResponse.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java b/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java index 94180e49..c27ed478 100644 --- a/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java +++ b/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java @@ -19,7 +19,7 @@ public static NoticeDataResponse of(Notice notice, Boolean isAvailable) { return NoticeDataResponse.builder() .imageUrl(notice.getImageUrl()) .redirectUrl(notice.getRedirectUrl()) - .startDate(toYearAndMonthFormattedString(notice.getCreatedAt())) + .startDate(toYearAndMonthFormattedString(notice.getStartDate().toLocalDateTime())) .endDate(toYearAndMonthFormattedString(notice.getEndDate().toLocalDateTime())) .isAvailable(isAvailable) .build(); From 1008a51d802a99e82b66e7952890e301febfa188 Mon Sep 17 00:00:00 2001 From: hyeonjeongs Date: Fri, 26 Jan 2024 15:35:06 +0900 Subject: [PATCH 03/11] =?UTF-8?q?isAvailable=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yello/server/domain/notice/service/NoticeService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/yello/server/domain/notice/service/NoticeService.java b/src/main/java/com/yello/server/domain/notice/service/NoticeService.java index d8764e73..31163fc6 100644 --- a/src/main/java/com/yello/server/domain/notice/service/NoticeService.java +++ b/src/main/java/com/yello/server/domain/notice/service/NoticeService.java @@ -24,7 +24,7 @@ public class NoticeService { public NoticeDataResponse findNotice(Long userId) { final User user = userRepository.getById(userId); Notice noticeData = noticeRepository.getTopNotice(); - return NoticeDataResponse.of(noticeData, compareNowAndEndData(noticeData.getEndDate())); + return NoticeDataResponse.of(noticeData, compareNowAndEndData(noticeData.getEndDate()) && noticeData.getIsAvailable()); } From 46a0252d3e192b130531da1f1424e06a221b4acf Mon Sep 17 00:00:00 2001 From: hyeonjeongs Date: Fri, 26 Jan 2024 21:48:35 +0900 Subject: [PATCH 04/11] =?UTF-8?q?YEL-185=20[feat]=20unit=20test=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/notice/dto/NoticeDataResponse.java | 5 +- .../exception/NoticeNotFoundException.java | 13 +++ .../notice/repository/NoticeRepository.java | 1 + .../repository/NoticeRepositoryImpl.java | 8 +- .../domain/notice/service/NoticeService.java | 2 + .../response/UserSubscribeDetailResponse.java | 3 +- .../yello/server/global/common/ErrorCode.java | 1 + .../global/common/factory/TimeFactory.java | 4 +- .../global/common/util/ConstantUtil.java | 2 + .../exception/ControllerExceptionAdvice.java | 4 +- .../authorization/small/AuthManagerTest.java | 6 +- .../authorization/small/AuthServiceTest.java | 6 +- .../friend/small/FriendServiceTest.java | 6 +- .../domain/notice/FakeNoticeRepository.java | 40 +++++++++ .../notice/medium/NoticeControllerTest.java | 5 ++ .../notice/small/NoticeServiceTest.java | 85 +++++++++++++++++++ .../domain/user/small/UserServiceTest.java | 6 +- .../domain/vote/small/VoteManagerTest.java | 6 +- .../domain/vote/small/VoteServiceTest.java | 6 +- .../firebase/small/FcmManagerTest.java | 6 +- .../yello/server/util/TestDataEntityUtil.java | 14 +++ .../server/util/TestDataRepositoryUtil.java | 19 ++++- .../com/yello/server/util/TestDataUtil.java | 3 + 23 files changed, 235 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/yello/server/domain/notice/exception/NoticeNotFoundException.java create mode 100644 src/test/java/com/yello/server/domain/notice/FakeNoticeRepository.java create mode 100644 src/test/java/com/yello/server/domain/notice/medium/NoticeControllerTest.java create mode 100644 src/test/java/com/yello/server/domain/notice/small/NoticeServiceTest.java diff --git a/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java b/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java index c27ed478..35a5ce73 100644 --- a/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java +++ b/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java @@ -6,6 +6,7 @@ import java.time.LocalDateTime; import static com.yello.server.global.common.factory.TimeFactory.toYearAndMonthFormattedString; +import static com.yello.server.global.common.util.ConstantUtil.PLUS_BASIC_TIME; @Builder public record NoticeDataResponse( @@ -19,8 +20,8 @@ public static NoticeDataResponse of(Notice notice, Boolean isAvailable) { return NoticeDataResponse.builder() .imageUrl(notice.getImageUrl()) .redirectUrl(notice.getRedirectUrl()) - .startDate(toYearAndMonthFormattedString(notice.getStartDate().toLocalDateTime())) - .endDate(toYearAndMonthFormattedString(notice.getEndDate().toLocalDateTime())) + .startDate(toYearAndMonthFormattedString(notice.getStartDate().toLocalDateTime(), PLUS_BASIC_TIME)) + .endDate(toYearAndMonthFormattedString(notice.getEndDate().toLocalDateTime(), PLUS_BASIC_TIME)) .isAvailable(isAvailable) .build(); } diff --git a/src/main/java/com/yello/server/domain/notice/exception/NoticeNotFoundException.java b/src/main/java/com/yello/server/domain/notice/exception/NoticeNotFoundException.java new file mode 100644 index 00000000..e53268ac --- /dev/null +++ b/src/main/java/com/yello/server/domain/notice/exception/NoticeNotFoundException.java @@ -0,0 +1,13 @@ +package com.yello.server.domain.notice.exception; + +import com.yello.server.global.common.ErrorCode; +import com.yello.server.global.exception.CustomException; +import lombok.Getter; + +@Getter +public class NoticeNotFoundException extends CustomException { + + public NoticeNotFoundException(ErrorCode error) { + super(error, "[NoticeNotFoundException] " + error.getMessage()); + } +} diff --git a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepository.java b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepository.java index 6d95c3f2..25e6d87f 100644 --- a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepository.java +++ b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepository.java @@ -7,5 +7,6 @@ public interface NoticeRepository { Notice getTopNotice(); + Notice save(Notice notice); } diff --git a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java index 1bb69da9..69ec529a 100644 --- a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java +++ b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java @@ -2,8 +2,6 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import com.yello.server.domain.notice.entity.Notice; -import com.yello.server.domain.purchase.exception.PurchaseConflictException; -import com.yello.server.global.common.ErrorCode; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @@ -27,4 +25,10 @@ public Notice getTopNotice() { .orderBy(notice.endDate.desc()) .fetchFirst(); } + + @Override + public Notice save(Notice notice) { + return null; + } + } diff --git a/src/main/java/com/yello/server/domain/notice/service/NoticeService.java b/src/main/java/com/yello/server/domain/notice/service/NoticeService.java index 31163fc6..530f8048 100644 --- a/src/main/java/com/yello/server/domain/notice/service/NoticeService.java +++ b/src/main/java/com/yello/server/domain/notice/service/NoticeService.java @@ -5,6 +5,7 @@ import com.yello.server.domain.notice.repository.NoticeRepository; import com.yello.server.domain.user.entity.User; import com.yello.server.domain.user.repository.UserRepository; +import lombok.Builder; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -15,6 +16,7 @@ import static com.yello.server.global.common.factory.TimeFactory.compareNowAndEndData; @Service +@Builder @RequiredArgsConstructor @Transactional(readOnly = true) public class NoticeService { diff --git a/src/main/java/com/yello/server/domain/user/dto/response/UserSubscribeDetailResponse.java b/src/main/java/com/yello/server/domain/user/dto/response/UserSubscribeDetailResponse.java index 30616613..a050f22b 100644 --- a/src/main/java/com/yello/server/domain/user/dto/response/UserSubscribeDetailResponse.java +++ b/src/main/java/com/yello/server/domain/user/dto/response/UserSubscribeDetailResponse.java @@ -1,6 +1,7 @@ package com.yello.server.domain.user.dto.response; import static com.yello.server.global.common.factory.TimeFactory.toYearAndMonthFormattedString; +import static com.yello.server.global.common.util.ConstantUtil.PLUS_SEVEN_TIME; import com.yello.server.domain.purchase.entity.Purchase; import lombok.Builder; @@ -16,7 +17,7 @@ public static UserSubscribeDetailResponse of(Purchase purchase) { return UserSubscribeDetailResponse.builder() .id(purchase.getUser().getId()) .subscribe(purchase.getUser().getSubscribe().getIntial()) - .expiredDate(toYearAndMonthFormattedString(purchase.getUpdatedAt())) + .expiredDate(toYearAndMonthFormattedString(purchase.getUpdatedAt(), PLUS_SEVEN_TIME)) .build(); } } diff --git a/src/main/java/com/yello/server/global/common/ErrorCode.java b/src/main/java/com/yello/server/global/common/ErrorCode.java index 985be011..b6d00ca8 100644 --- a/src/main/java/com/yello/server/global/common/ErrorCode.java +++ b/src/main/java/com/yello/server/global/common/ErrorCode.java @@ -90,6 +90,7 @@ public enum ErrorCode { NOT_EQUAL_TRANSACTION_EXCEPTION(NOT_FOUND, "동일하지 않은 거래입니다."), NOT_FOUND_NOTIFICATION_TYPE_EXCEPTION(NOT_FOUND, "존재하지 않는 알림 타입 입니다"), NOT_FOUND_USER_SUBSCRIBE_EXCEPTION(NOT_FOUND, "유저의 구독정보가 존재하지 않습니다."), + NOT_FOUND_NOTICE_EXCEPTION(NOT_FOUND, "공지가 존재하지 않습니다."), /** * 409 CONFLICT diff --git a/src/main/java/com/yello/server/global/common/factory/TimeFactory.java b/src/main/java/com/yello/server/global/common/factory/TimeFactory.java index d54b1737..952e11db 100644 --- a/src/main/java/com/yello/server/global/common/factory/TimeFactory.java +++ b/src/main/java/com/yello/server/global/common/factory/TimeFactory.java @@ -53,11 +53,11 @@ public static LocalDateTime minusTime(LocalDateTime localDateTime, int time) { return localDateTime.minusMinutes(time); } - public static String toYearAndMonthFormattedString(LocalDateTime localDateTime) { + public static String toYearAndMonthFormattedString(LocalDateTime localDateTime, int time) { if (localDateTime == null) { return ""; } - LocalDateTime dateTimePlusSevenDays = localDateTime.plusDays(7); + LocalDateTime dateTimePlusSevenDays = localDateTime.plusDays(time); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); return dateTimePlusSevenDays.format(dateTimeFormatter); } diff --git a/src/main/java/com/yello/server/global/common/util/ConstantUtil.java b/src/main/java/com/yello/server/global/common/util/ConstantUtil.java index 44213c44..ab76a259 100644 --- a/src/main/java/com/yello/server/global/common/util/ConstantUtil.java +++ b/src/main/java/com/yello/server/global/common/util/ConstantUtil.java @@ -65,6 +65,8 @@ public class ConstantUtil { public static final int REFUND_TWO_TICKET = 2; public static final int REFUND_FIVE_TICKET = 5; public static final int NO_FRIEND_COUNT = 0; + public static final int PLUS_SEVEN_TIME = 7; + public static final int PLUS_BASIC_TIME = 0; private ConstantUtil() { diff --git a/src/main/java/com/yello/server/global/exception/ControllerExceptionAdvice.java b/src/main/java/com/yello/server/global/exception/ControllerExceptionAdvice.java index 4524a428..033d32b4 100644 --- a/src/main/java/com/yello/server/global/exception/ControllerExceptionAdvice.java +++ b/src/main/java/com/yello/server/global/exception/ControllerExceptionAdvice.java @@ -23,6 +23,7 @@ import com.yello.server.domain.friend.exception.FriendException; import com.yello.server.domain.friend.exception.FriendNotFoundException; import com.yello.server.domain.group.exception.GroupNotFoundException; +import com.yello.server.domain.notice.exception.NoticeNotFoundException; import com.yello.server.domain.purchase.exception.AppleBadRequestException; import com.yello.server.domain.purchase.exception.AppleTokenServerErrorException; import com.yello.server.domain.purchase.exception.GoogleBadRequestException; @@ -189,7 +190,8 @@ public ResponseEntity ForbiddenException(CustomException exception RedisNotFoundException.class, PurchaseNotFoundException.class, GoogleTokenNotFoundException.class, - UserAdminNotFoundException.class + UserAdminNotFoundException.class, + NoticeNotFoundException.class }) public ResponseEntity NotFoundException(CustomException exception) { return ResponseEntity.status(NOT_FOUND) diff --git a/src/test/java/com/yello/server/domain/authorization/small/AuthManagerTest.java b/src/test/java/com/yello/server/domain/authorization/small/AuthManagerTest.java index 38190a5e..31174b07 100644 --- a/src/test/java/com/yello/server/domain/authorization/small/AuthManagerTest.java +++ b/src/test/java/com/yello/server/domain/authorization/small/AuthManagerTest.java @@ -15,6 +15,8 @@ import com.yello.server.domain.friend.FakeFriendRepository; import com.yello.server.domain.friend.repository.FriendRepository; import com.yello.server.domain.group.entity.UserGroupType; +import com.yello.server.domain.notice.FakeNoticeRepository; +import com.yello.server.domain.notice.repository.NoticeRepository; import com.yello.server.domain.purchase.FakePurchaseRepository; import com.yello.server.domain.purchase.repository.PurchaseRepository; import com.yello.server.domain.question.FakeQuestionGroupTypeRepository; @@ -51,13 +53,15 @@ public class AuthManagerTest { private final VoteRepository voteRepository = new FakeVoteRepository(); private final QuestionGroupTypeRepository questionGroupTypeRepository = new FakeQuestionGroupTypeRepository(questionRepository); private final PurchaseRepository purchaseRepository = new FakePurchaseRepository(); + private final NoticeRepository noticeRepository = new FakeNoticeRepository(); private final TestDataRepositoryUtil testDataUtil = new TestDataRepositoryUtil( userRepository, voteRepository, questionRepository, friendRepository, questionGroupTypeRepository, - purchaseRepository + purchaseRepository, + noticeRepository ); private AuthManager authManager; diff --git a/src/test/java/com/yello/server/domain/authorization/small/AuthServiceTest.java b/src/test/java/com/yello/server/domain/authorization/small/AuthServiceTest.java index f7fd5916..b8fdb8db 100644 --- a/src/test/java/com/yello/server/domain/authorization/small/AuthServiceTest.java +++ b/src/test/java/com/yello/server/domain/authorization/small/AuthServiceTest.java @@ -30,6 +30,8 @@ import com.yello.server.domain.group.entity.UserGroupType; import com.yello.server.domain.group.exception.GroupNotFoundException; import com.yello.server.domain.group.repository.UserGroupRepository; +import com.yello.server.domain.notice.FakeNoticeRepository; +import com.yello.server.domain.notice.repository.NoticeRepository; import com.yello.server.domain.purchase.FakePurchaseRepository; import com.yello.server.domain.purchase.repository.PurchaseRepository; import com.yello.server.domain.question.FakeQuestionGroupTypeRepository; @@ -101,13 +103,15 @@ public class AuthServiceTest { ); private final VoteRepository voteRepository = new FakeVoteRepository(); private final PurchaseRepository purchaseRepository = new FakePurchaseRepository(); + private final NoticeRepository noticeRepository = new FakeNoticeRepository(); private final TestDataRepositoryUtil testDataUtil = new TestDataRepositoryUtil( userRepository, voteRepository, questionRepository, friendRepository, questionGroupTypeRepository, - purchaseRepository + purchaseRepository, + noticeRepository ); private final VoteManager voteManager = new FakeVoteManager( userRepository, questionRepository, voteRepository, friendRepository, diff --git a/src/test/java/com/yello/server/domain/friend/small/FriendServiceTest.java b/src/test/java/com/yello/server/domain/friend/small/FriendServiceTest.java index 43580ad4..b3492577 100644 --- a/src/test/java/com/yello/server/domain/friend/small/FriendServiceTest.java +++ b/src/test/java/com/yello/server/domain/friend/small/FriendServiceTest.java @@ -17,6 +17,8 @@ import com.yello.server.domain.friend.repository.FriendRepository; import com.yello.server.domain.friend.service.FriendService; import com.yello.server.domain.group.entity.UserGroupType; +import com.yello.server.domain.notice.FakeNoticeRepository; +import com.yello.server.domain.notice.repository.NoticeRepository; import com.yello.server.domain.purchase.FakePurchaseRepository; import com.yello.server.domain.purchase.repository.PurchaseRepository; import com.yello.server.domain.question.FakeQuestionGroupTypeRepository; @@ -58,13 +60,15 @@ class FriendServiceTest { new FakeVoteManager(userRepository, questionRepository, voteRepository, friendRepository, userManager); private final PurchaseRepository purchaseRepository = new FakePurchaseRepository(); + private final NoticeRepository noticeRepository = new FakeNoticeRepository(); private final TestDataRepositoryUtil testDataUtil = new TestDataRepositoryUtil( userRepository, voteRepository, questionRepository, friendRepository, questionGroupTypeRepository, - purchaseRepository + purchaseRepository, + noticeRepository ); private FriendService friendService; private User user1; diff --git a/src/test/java/com/yello/server/domain/notice/FakeNoticeRepository.java b/src/test/java/com/yello/server/domain/notice/FakeNoticeRepository.java new file mode 100644 index 00000000..c8c72682 --- /dev/null +++ b/src/test/java/com/yello/server/domain/notice/FakeNoticeRepository.java @@ -0,0 +1,40 @@ +package com.yello.server.domain.notice; + +import static com.yello.server.global.common.ErrorCode.NOT_FOUND_NOTICE_EXCEPTION; + +import com.yello.server.domain.notice.entity.Notice; +import com.yello.server.domain.notice.exception.NoticeNotFoundException; +import com.yello.server.domain.notice.repository.NoticeRepository; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +public class FakeNoticeRepository implements NoticeRepository { + + private List data = new ArrayList<>(); + private Long id = 0L; + + @Override + public Notice getTopNotice() { + return data.stream() + .sorted(Comparator.comparing(Notice::getEndDate).reversed()) + .findFirst() + .orElseThrow(() -> new NoticeNotFoundException(NOT_FOUND_NOTICE_EXCEPTION)); + } + + @Override + public Notice save(Notice notice) { + final Notice newNotice = Notice.builder() + .id(notice.getId()==null ? ++id : notice.getId()) + .endDate(notice.getEndDate()) + .imageUrl(notice.getImageUrl()) + .startDate(notice.getStartDate()) + .redirectUrl(notice.getRedirectUrl()) + .isAvailable(notice.getIsAvailable()) + .build(); + + data.add(newNotice); + return newNotice; + } +} diff --git a/src/test/java/com/yello/server/domain/notice/medium/NoticeControllerTest.java b/src/test/java/com/yello/server/domain/notice/medium/NoticeControllerTest.java new file mode 100644 index 00000000..d16b1129 --- /dev/null +++ b/src/test/java/com/yello/server/domain/notice/medium/NoticeControllerTest.java @@ -0,0 +1,5 @@ +package com.yello.server.domain.notice.medium; + +public class NoticeControllerTest { + +} diff --git a/src/test/java/com/yello/server/domain/notice/small/NoticeServiceTest.java b/src/test/java/com/yello/server/domain/notice/small/NoticeServiceTest.java new file mode 100644 index 00000000..d0302ae2 --- /dev/null +++ b/src/test/java/com/yello/server/domain/notice/small/NoticeServiceTest.java @@ -0,0 +1,85 @@ +package com.yello.server.domain.notice.small; + + +import static org.assertj.core.api.Assertions.assertThat; + +import com.yello.server.domain.friend.FakeFriendRepository; +import com.yello.server.domain.friend.repository.FriendRepository; +import com.yello.server.domain.group.entity.UserGroupType; +import com.yello.server.domain.notice.FakeNoticeRepository; +import com.yello.server.domain.notice.dto.NoticeDataResponse; +import com.yello.server.domain.notice.entity.Notice; +import com.yello.server.domain.notice.repository.NoticeRepository; +import com.yello.server.domain.notice.service.NoticeService; +import com.yello.server.domain.purchase.FakePurchaseRepository; +import com.yello.server.domain.purchase.repository.PurchaseRepository; +import com.yello.server.domain.question.FakeQuestionGroupTypeRepository; +import com.yello.server.domain.question.FakeQuestionRepository; +import com.yello.server.domain.question.repository.QuestionGroupTypeRepository; +import com.yello.server.domain.question.repository.QuestionRepository; +import com.yello.server.domain.user.FakeUserRepository; +import com.yello.server.domain.user.entity.Subscribe; +import com.yello.server.domain.user.entity.User; +import com.yello.server.domain.user.repository.UserRepository; +import com.yello.server.domain.vote.FakeVoteRepository; +import com.yello.server.domain.vote.repository.VoteRepository; +import com.yello.server.util.TestDataRepositoryUtil; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; + +@DisplayName("NoticeService 에서") +@DisplayNameGeneration(ReplaceUnderscores.class) +public class NoticeServiceTest { + private final NoticeRepository noticeRepository = new FakeNoticeRepository(); + private final FriendRepository friendRepository = new FakeFriendRepository(); + private final UserRepository userRepository = new FakeUserRepository(friendRepository); + private final QuestionRepository questionRepository = new FakeQuestionRepository(); + private final VoteRepository voteRepository = new FakeVoteRepository(); + private final QuestionGroupTypeRepository + questionGroupTypeRepository = new FakeQuestionGroupTypeRepository(questionRepository); + private final PurchaseRepository purchaseRepository = new FakePurchaseRepository(); + private NoticeService noticeService; + private User user1; + private final TestDataRepositoryUtil testDataUtil = new TestDataRepositoryUtil( + userRepository, + voteRepository, + questionRepository, + friendRepository, + questionGroupTypeRepository, + purchaseRepository, + noticeRepository + ); + + @BeforeEach + void init() { + this.noticeService = NoticeService.builder() + .noticeRepository(noticeRepository) + .userRepository(userRepository) + .build(); + + final User user = testDataUtil.generateUser(1L, 1L, UserGroupType.HIGH_SCHOOL); + user.setSubscribe(Subscribe.ACTIVE); + final Notice notice = testDataUtil.genereateNotice(1L); + noticeRepository.save(notice); + } + + @Test + void 공지_조회에_성공합니다() { + // given + final Long userId = 1L; + + // when + final NoticeDataResponse notice = noticeService.findNotice(userId); + + // then + assertThat(notice.isAvailable()).isTrue(); + + } +} diff --git a/src/test/java/com/yello/server/domain/user/small/UserServiceTest.java b/src/test/java/com/yello/server/domain/user/small/UserServiceTest.java index f2b7ce91..45e76dd4 100644 --- a/src/test/java/com/yello/server/domain/user/small/UserServiceTest.java +++ b/src/test/java/com/yello/server/domain/user/small/UserServiceTest.java @@ -8,6 +8,8 @@ import com.yello.server.domain.friend.FakeFriendRepository; import com.yello.server.domain.friend.repository.FriendRepository; import com.yello.server.domain.group.entity.UserGroupType; +import com.yello.server.domain.notice.FakeNoticeRepository; +import com.yello.server.domain.notice.repository.NoticeRepository; import com.yello.server.domain.purchase.FakePurchaseRepository; import com.yello.server.domain.purchase.entity.Purchase; import com.yello.server.domain.purchase.repository.PurchaseRepository; @@ -52,13 +54,15 @@ class UserServiceTest { private final TokenRepository tokenRepository = new FakeTokenRepository(); private final UserRepository userRepository = new FakeUserRepository(friendRepository); private final VoteRepository voteRepository = new FakeVoteRepository(); + private final NoticeRepository noticeRepository = new FakeNoticeRepository(); private final TestDataRepositoryUtil testDataUtil = new TestDataRepositoryUtil( userRepository, voteRepository, questionRepository, friendRepository, questionGroupTypeRepository, - purchaseRepository + purchaseRepository, + noticeRepository ); private UserService userService; diff --git a/src/test/java/com/yello/server/domain/vote/small/VoteManagerTest.java b/src/test/java/com/yello/server/domain/vote/small/VoteManagerTest.java index 5943c1c6..6d3c949e 100644 --- a/src/test/java/com/yello/server/domain/vote/small/VoteManagerTest.java +++ b/src/test/java/com/yello/server/domain/vote/small/VoteManagerTest.java @@ -6,6 +6,8 @@ import com.yello.server.domain.friend.FakeFriendRepository; import com.yello.server.domain.friend.repository.FriendRepository; import com.yello.server.domain.group.entity.UserGroupType; +import com.yello.server.domain.notice.FakeNoticeRepository; +import com.yello.server.domain.notice.repository.NoticeRepository; import com.yello.server.domain.purchase.FakePurchaseRepository; import com.yello.server.domain.purchase.repository.PurchaseRepository; import com.yello.server.domain.question.FakeQuestionGroupTypeRepository; @@ -45,13 +47,15 @@ public class VoteManagerTest { private final QuestionGroupTypeRepository questionGroupTypeRepository = new FakeQuestionGroupTypeRepository(questionRepository); private final PurchaseRepository purchaseRepository = new FakePurchaseRepository(); + private final NoticeRepository noticeRepository = new FakeNoticeRepository(); private final TestDataRepositoryUtil testDataUtil = new TestDataRepositoryUtil( userRepository, voteRepository, questionRepository, friendRepository, questionGroupTypeRepository, - purchaseRepository + purchaseRepository, + noticeRepository ); private VoteManager voteManager; private List questionData = new ArrayList<>(); diff --git a/src/test/java/com/yello/server/domain/vote/small/VoteServiceTest.java b/src/test/java/com/yello/server/domain/vote/small/VoteServiceTest.java index 8b29df7b..109356e4 100644 --- a/src/test/java/com/yello/server/domain/vote/small/VoteServiceTest.java +++ b/src/test/java/com/yello/server/domain/vote/small/VoteServiceTest.java @@ -11,6 +11,8 @@ import com.yello.server.domain.keyword.FakeKeywordRepository; import com.yello.server.domain.keyword.dto.response.KeywordCheckResponse; import com.yello.server.domain.keyword.repository.KeywordRepository; +import com.yello.server.domain.notice.FakeNoticeRepository; +import com.yello.server.domain.notice.repository.NoticeRepository; import com.yello.server.domain.purchase.FakePurchaseRepository; import com.yello.server.domain.purchase.repository.PurchaseRepository; import com.yello.server.domain.question.FakeQuestionGroupTypeRepository; @@ -65,6 +67,7 @@ public class VoteServiceTest { private final QuestionRepository questionRepository = new FakeQuestionRepository(); private final QuestionGroupTypeRepository questionGroupTypeRepository = new FakeQuestionGroupTypeRepository(questionRepository); private final PurchaseRepository purchaseRepository = new FakePurchaseRepository(); + private final NoticeRepository noticeRepository = new FakeNoticeRepository(); private final VoteManager voteManager = new FakeVoteManager( userRepository, questionRepository, @@ -78,7 +81,8 @@ public class VoteServiceTest { questionRepository, friendRepository, questionGroupTypeRepository, - purchaseRepository + purchaseRepository, + noticeRepository ); private final CooldownRepository cooldownRepository = new FakeCooldownRepository(); private final KeywordRepository keywordRepository = new FakeKeywordRepository(); diff --git a/src/test/java/com/yello/server/infrastructure/firebase/small/FcmManagerTest.java b/src/test/java/com/yello/server/infrastructure/firebase/small/FcmManagerTest.java index a43b90f1..13ef3670 100644 --- a/src/test/java/com/yello/server/infrastructure/firebase/small/FcmManagerTest.java +++ b/src/test/java/com/yello/server/infrastructure/firebase/small/FcmManagerTest.java @@ -3,6 +3,8 @@ import com.yello.server.domain.friend.FakeFriendRepository; import com.yello.server.domain.friend.repository.FriendRepository; import com.yello.server.domain.group.entity.UserGroupType; +import com.yello.server.domain.notice.FakeNoticeRepository; +import com.yello.server.domain.notice.repository.NoticeRepository; import com.yello.server.domain.purchase.FakePurchaseRepository; import com.yello.server.domain.purchase.repository.PurchaseRepository; import com.yello.server.domain.question.FakeQuestionGroupTypeRepository; @@ -36,13 +38,15 @@ public class FcmManagerTest { private final QuestionGroupTypeRepository questionGroupTypeRepository = new FakeQuestionGroupTypeRepository(questionRepository); private final PurchaseRepository purchaseRepository = new FakePurchaseRepository(); + private final NoticeRepository noticeRepository = new FakeNoticeRepository(); private final TestDataRepositoryUtil testDataUtil = new TestDataRepositoryUtil( userRepository, voteRepository, questionRepository, friendRepository, questionGroupTypeRepository, - purchaseRepository + purchaseRepository, + noticeRepository ); private FCMManager fcmManager; diff --git a/src/test/java/com/yello/server/util/TestDataEntityUtil.java b/src/test/java/com/yello/server/util/TestDataEntityUtil.java index 72a6fab6..52113a71 100644 --- a/src/test/java/com/yello/server/util/TestDataEntityUtil.java +++ b/src/test/java/com/yello/server/util/TestDataEntityUtil.java @@ -3,6 +3,7 @@ import com.yello.server.domain.friend.entity.Friend; import com.yello.server.domain.group.entity.UserGroup; import com.yello.server.domain.group.entity.UserGroupType; +import com.yello.server.domain.notice.entity.Notice; import com.yello.server.domain.purchase.entity.Gateway; import com.yello.server.domain.purchase.entity.ProductType; import com.yello.server.domain.purchase.entity.Purchase; @@ -15,6 +16,7 @@ import com.yello.server.domain.user.entity.User; import com.yello.server.domain.vote.entity.Vote; import java.time.LocalDateTime; +import java.time.ZonedDateTime; public class TestDataEntityUtil implements TestDataUtil { @@ -138,4 +140,16 @@ public Purchase generatePurchase(long index, User user) { .updatedAt(LocalDateTime.now()) .build(); } + + @Override + public Notice genereateNotice(long index) { + return Notice.builder() + .id(index) + .endDate(ZonedDateTime.now().minusHours(3)) + .imageUrl("imageUrl") + .startDate(ZonedDateTime.now().minusHours(10)) + .redirectUrl("redirectUrl") + .isAvailable(true) + .build(); + } } diff --git a/src/test/java/com/yello/server/util/TestDataRepositoryUtil.java b/src/test/java/com/yello/server/util/TestDataRepositoryUtil.java index c0a30e56..53284316 100644 --- a/src/test/java/com/yello/server/util/TestDataRepositoryUtil.java +++ b/src/test/java/com/yello/server/util/TestDataRepositoryUtil.java @@ -4,6 +4,8 @@ import com.yello.server.domain.friend.repository.FriendRepository; import com.yello.server.domain.group.entity.UserGroup; import com.yello.server.domain.group.entity.UserGroupType; +import com.yello.server.domain.notice.entity.Notice; +import com.yello.server.domain.notice.repository.NoticeRepository; import com.yello.server.domain.purchase.entity.Gateway; import com.yello.server.domain.purchase.entity.ProductType; import com.yello.server.domain.purchase.entity.Purchase; @@ -21,6 +23,7 @@ import com.yello.server.domain.vote.entity.Vote; import com.yello.server.domain.vote.repository.VoteRepository; import java.time.LocalDateTime; +import java.time.ZonedDateTime; public class TestDataRepositoryUtil implements TestDataUtil { @@ -30,17 +33,19 @@ public class TestDataRepositoryUtil implements TestDataUtil { private final QuestionRepository questionRepository; private final UserRepository userRepository; private final VoteRepository voteRepository; + private final NoticeRepository noticeRepository; public TestDataRepositoryUtil(UserRepository userRepository, VoteRepository voteRepository, QuestionRepository questionRepository, FriendRepository friendRepository, QuestionGroupTypeRepository questionGroupTypeRepository, - PurchaseRepository purchaseRepository) { + PurchaseRepository purchaseRepository, NoticeRepository noticeRepository) { this.userRepository = userRepository; this.voteRepository = voteRepository; this.questionRepository = questionRepository; this.friendRepository = friendRepository; this.questionGroupTypeRepository = questionGroupTypeRepository; this.purchaseRepository = purchaseRepository; + this.noticeRepository = noticeRepository; } @Override @@ -164,4 +169,16 @@ public Purchase generatePurchase(long index, User user) { .build() ); } + + @Override + public Notice genereateNotice(long index) { + return Notice.builder() + .id(index) + .endDate(ZonedDateTime.now().plusDays(3)) + .imageUrl("imageUrl") + .startDate(ZonedDateTime.now().minusDays(4)) + .redirectUrl("redirectUrl") + .isAvailable(true) + .build(); + } } diff --git a/src/test/java/com/yello/server/util/TestDataUtil.java b/src/test/java/com/yello/server/util/TestDataUtil.java index e4d8db7a..277061e7 100644 --- a/src/test/java/com/yello/server/util/TestDataUtil.java +++ b/src/test/java/com/yello/server/util/TestDataUtil.java @@ -3,6 +3,7 @@ import com.yello.server.domain.friend.entity.Friend; import com.yello.server.domain.group.entity.UserGroup; import com.yello.server.domain.group.entity.UserGroupType; +import com.yello.server.domain.notice.entity.Notice; import com.yello.server.domain.purchase.entity.Purchase; import com.yello.server.domain.question.entity.Question; import com.yello.server.domain.question.entity.QuestionGroupType; @@ -26,5 +27,7 @@ public interface TestDataUtil { QuestionGroupType generateQuestionGroupType(long index, Question question); Purchase generatePurchase(long index, User user); + + Notice genereateNotice(long index); } From 676fd6adfb891cf7e35d2423d3af2b57a16d1fdb Mon Sep 17 00:00:00 2001 From: hyeonjeongs Date: Fri, 26 Jan 2024 22:19:12 +0900 Subject: [PATCH 05/11] =?UTF-8?q?YEL-185=20[feat]=20controller=20test=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/find-notice.adoc | 32 +----- .../notice/medium/NoticeControllerTest.java | 98 +++++++++++++++++++ .../yello/server/util/TestDataEntityUtil.java | 4 +- .../server/util/TestDataRepositoryUtil.java | 4 +- 4 files changed, 107 insertions(+), 31 deletions(-) diff --git a/src/docs/asciidoc/find-notice.adoc b/src/docs/asciidoc/find-notice.adoc index 099330b5..eceebdbc 100644 --- a/src/docs/asciidoc/find-notice.adoc +++ b/src/docs/asciidoc/find-notice.adoc @@ -1,36 +1,13 @@ :reproducible: -== 공지 조회 (명세) +== 공지 조회 === 요청 -[http] ----- -GET /api/v1/notice HTTP/1.1 -Authorization: Bearer your-access-token ----- +include::{snippets}/api/v1/notice/http-request.adoc[] === 응답 -[http,json] ----- -HTTP/1.1 200 OK -Vary: Origin -Vary: Access-Control-Request-Method -Vary: Access-Control-Request-Headers -Content-Type: application/json - -{ - "status": 200, - "message": "공지 조회에 성공하였습니다.", - "data": { - "imageUrl" : "url here", - "redirectUrl": "redirect url here", - "startDate": "2021.01.12", - "endDate": "2021.01.17", - "isAvailable": true - } -} ----- +include::{snippets}/api/v1/notice/http-response.adoc[] *필드 타입* @@ -47,10 +24,11 @@ Content-Type: application/json === NOTE - 공지 정보를 조회하는 API입니다. -- 유효한 1개의 공지를 반환합니다. +- isAvailable true일 때, 유효한 1개의 공지를 반환합니다. * 요구사항에 따라 여러개의 공지를 반환할 수 있도록 염두하고 있습니다. * 반환되는 공지를 무조건 View에 띄워주시면 되겠습니다. === CHANGELOG +- 2024.01.26 API 릴리즈 - 2024.01.09 명세 작성 \ No newline at end of file diff --git a/src/test/java/com/yello/server/domain/notice/medium/NoticeControllerTest.java b/src/test/java/com/yello/server/domain/notice/medium/NoticeControllerTest.java index d16b1129..e3cdccd0 100644 --- a/src/test/java/com/yello/server/domain/notice/medium/NoticeControllerTest.java +++ b/src/test/java/com/yello/server/domain/notice/medium/NoticeControllerTest.java @@ -1,5 +1,103 @@ package com.yello.server.domain.notice.medium; + +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.BDDMockito.given; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.removeHeaders; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.yello.server.domain.authorization.filter.JwtExceptionFilter; +import com.yello.server.domain.authorization.filter.JwtFilter; +import com.yello.server.domain.group.entity.UserGroupType; +import com.yello.server.domain.notice.controller.NoticeController; +import com.yello.server.domain.notice.dto.NoticeDataResponse; +import com.yello.server.domain.notice.entity.Notice; +import com.yello.server.domain.notice.service.NoticeService; +import com.yello.server.domain.purchase.controller.PurchaseController; +import com.yello.server.domain.user.entity.User; +import com.yello.server.global.exception.ControllerExceptionAdvice; +import com.yello.server.util.TestDataEntityUtil; +import com.yello.server.util.TestDataUtil; +import com.yello.server.util.WithAccessTokenUser; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; +import org.springframework.http.HttpHeaders; +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +import org.springframework.restdocs.operation.preprocess.Preprocessors; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +@AutoConfigureRestDocs +@WebMvcTest( + controllers = NoticeController.class, + excludeFilters = { + @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = JwtFilter.class), + @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = JwtExceptionFilter.class), + @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ControllerExceptionAdvice.class) + }) +@WithAccessTokenUser +@DisplayNameGeneration(ReplaceUnderscores.class) +@DisplayName("Notice 컨트롤러에서") public class NoticeControllerTest { + final String[] excludeRequestHeaders = {"X-CSRF-TOKEN", "Host"}; + final String[] excludeResponseHeaders = + {"X-Content-Type-Options", "X-XSS-Protection", "Cache-Control", "Pragma", + "Expires", "X-Frame-Options", "Content-Length"}; + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @MockBean + private NoticeService noticeService; + + private TestDataUtil testDataUtil = new TestDataEntityUtil(); + private User user; + private Notice notice; + + + @BeforeEach + void init() { + user = testDataUtil.generateUser(1L, 1L, UserGroupType.HIGH_SCHOOL); + notice = testDataUtil.genereateNotice(1L); + } + + @Test + void 공지_조회하기_검증에_성공합니다() throws Exception { + // given + final NoticeDataResponse noticeDataResponse = NoticeDataResponse.of(notice, true); + + given(noticeService.findNotice(anyLong())) + .willReturn(noticeDataResponse); + + // when + // then + mockMvc.perform(RestDocumentationRequestBuilders + .get("/api/v1/notice") + .header(HttpHeaders.AUTHORIZATION, "Bearer your-access-token")) + .andDo(print()) + .andDo(document("api/v1/notice", + Preprocessors.preprocessRequest(prettyPrint(), + removeHeaders(excludeRequestHeaders)), + Preprocessors.preprocessResponse(prettyPrint(), + removeHeaders(excludeResponseHeaders))) + ) + .andExpect(MockMvcResultMatchers.status().isOk()); + } + } diff --git a/src/test/java/com/yello/server/util/TestDataEntityUtil.java b/src/test/java/com/yello/server/util/TestDataEntityUtil.java index 52113a71..4ef9c077 100644 --- a/src/test/java/com/yello/server/util/TestDataEntityUtil.java +++ b/src/test/java/com/yello/server/util/TestDataEntityUtil.java @@ -145,9 +145,9 @@ public Purchase generatePurchase(long index, User user) { public Notice genereateNotice(long index) { return Notice.builder() .id(index) - .endDate(ZonedDateTime.now().minusHours(3)) + .endDate(ZonedDateTime.now().minusDays(3)) .imageUrl("imageUrl") - .startDate(ZonedDateTime.now().minusHours(10)) + .startDate(ZonedDateTime.now().minusDays(10)) .redirectUrl("redirectUrl") .isAvailable(true) .build(); diff --git a/src/test/java/com/yello/server/util/TestDataRepositoryUtil.java b/src/test/java/com/yello/server/util/TestDataRepositoryUtil.java index 53284316..db4a965f 100644 --- a/src/test/java/com/yello/server/util/TestDataRepositoryUtil.java +++ b/src/test/java/com/yello/server/util/TestDataRepositoryUtil.java @@ -172,13 +172,13 @@ public Purchase generatePurchase(long index, User user) { @Override public Notice genereateNotice(long index) { - return Notice.builder() + return noticeRepository.save(Notice.builder() .id(index) .endDate(ZonedDateTime.now().plusDays(3)) .imageUrl("imageUrl") .startDate(ZonedDateTime.now().minusDays(4)) .redirectUrl("redirectUrl") .isAvailable(true) - .build(); + .build()); } } From 5469dc963f88999fde9cbdd72df49c5bd8cc5a36 Mon Sep 17 00:00:00 2001 From: hyeonjeongs Date: Fri, 26 Jan 2024 22:41:03 +0900 Subject: [PATCH 06/11] =?UTF-8?q?YEL-185=20[feat]=20=ED=83=80=EC=9E=84?= =?UTF-8?q?=EB=9D=BC=EC=9D=B8=20=EC=A1=B0=ED=9A=8C=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EB=AA=85=EC=84=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/find-friend-votes-v2.adoc | 98 +++++++++++++++++++++ src/docs/asciidoc/index.adoc | 4 +- 2 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/docs/asciidoc/find-friend-votes-v2.adoc diff --git a/src/docs/asciidoc/find-friend-votes-v2.adoc b/src/docs/asciidoc/find-friend-votes-v2.adoc new file mode 100644 index 00000000..32940e36 --- /dev/null +++ b/src/docs/asciidoc/find-friend-votes-v2.adoc @@ -0,0 +1,98 @@ +:reproducible: +== 친구 투표 전체 조회 (명세) + +=== 요청 + +[http] + +---- + +GET /v2/vote/friend?page={}&type={} HTTP/1.1 +Authorization: Bearer your-access-token +Content-Type: application-json + +---- + +*업데이트 예정* +- "type": "send" | null + +|=== +|`+type+`| 조회할 쪽지 종류 (null -> 모든쪽지, send-> 보낸쪽지) +|=== + +=== 응답 + +[http, json] +---- + +{ + "status" : 200, + "message" : "투표 조회에 성공했습니다.", + "data" : { + "totalCount" : 1, + "friendVotes" : [ { + "id" : 1, + "senderId" : 1, + "senderName" : "name1", + "senderGender" : "MALE", + "senderYelloId" : "MALE", + "senderProfileImage": "imageUrl", + "receiverId" : 2, + "receiverName" : "name2", + "receiverGender" : "MALE", + "receiverYelloId" : "MALE", + "receiverProfileImage" : "test image", + "vote" : { + "nameHead" : "나는", + "nameFoot" : "와", + "keywordHead" : "멋진", + "keyword" : "test", + "keywordFoot" : "에서 놀고싶어" + }, + "isHintUsed" : false, + "createdAt" : "0초 전" + "isUserSenderVote" : true + } ] + } +} + +---- + +*필드 타입* + +- "totalCount": Integer +- "friendVotes": *FriendVote*[] +- "isUserSenderVote" : Boolean (내가 보냈는지 여부) +- *FriendVote* +* "id": Long +* "senderId" : Long +* "senderName" : String +* "senderYelloId" : String +* "senderGender": "MALE" | "FEMALE" +* "senderProfileImage" : String +* "receiverId" : Long +* "receiverName": String +* "receiverYelloId" : String +* "receiverGender": "MALE" | "FEMALE" +* "receiverProfileImage": String +* "vote": *Vote* +* "isHintUsed": Boolean +* "createdAt": "{0}초 전" | "{0}분 전" | "{0}시간 전" | "{0}일 전" + +- *Vote* +* "nameHead": String +* "nameFoot": String +* "keywordHead": String +* "keyword": String +* "keywordFoot": String + +=== NOTE + +- 모든 종류의 쪽지를 조회할 때 `/api/v1/vote/friend?page=0` 으로 요청해주세요 +* `type=` 을 명시하지 마세요 +- 내가 보낸 쪽지를 조회할 때 `/api/v1/vote/friend?page=0&type=send` 으로 요청해주세요 +- `senderGender` 필드가 다른 API와 일관되지 못한점 미안해요 ㅠ + +=== CHANGELOG +- 2024.01.26 필드 명세 업데이트 +- 2024.01.09 `type` 명세 업데이트 \ No newline at end of file diff --git a/src/docs/asciidoc/index.adoc b/src/docs/asciidoc/index.adoc index be2036de..97520219 100644 --- a/src/docs/asciidoc/index.adoc +++ b/src/docs/asciidoc/index.adoc @@ -53,7 +53,7 @@ * link:find-votes.html[내 투표 전체 조회하기] -* ⬆️ link:find-friend-votes.html[친구 투표 전체 조회하기, 2024-01-09] +* ⬆️ link:find-friend-votes.html[친구 투표 전체 조회하기 (명세), 2024-01-09] * link:get-unread-vote.html[읽지 않은 쪽지 개수 조회하기] @@ -102,4 +102,4 @@ === Notice API -* 🆕 link:find-notice.html[공지 조회 (명세), 2024-01-09] \ No newline at end of file +* 🆕 link:find-notice.html[공지 조회, 2024-01-26] \ No newline at end of file From f0526a13f2b5979c8ff6ccd04b54b8a52f45aa2e Mon Sep 17 00:00:00 2001 From: hyeonjeongs Date: Fri, 26 Jan 2024 22:41:58 +0900 Subject: [PATCH 07/11] =?UTF-8?q?YEL-185=20[feat]=20=ED=83=80=EC=9E=84?= =?UTF-8?q?=EB=9D=BC=EC=9D=B8=20=EC=A1=B0=ED=9A=8C=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EB=AA=85=EC=84=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../static/docs/check-vote-available.html | 2 +- .../resources/static/docs/find-notice.html | 35 ++++++++++--------- src/main/resources/static/docs/google.html | 2 +- .../resources/static/docs/purchase-info.html | 2 +- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/main/resources/static/docs/check-vote-available.html b/src/main/resources/static/docs/check-vote-available.html index 25e39451..c60d3e17 100644 --- a/src/main/resources/static/docs/check-vote-available.html +++ b/src/main/resources/static/docs/check-vote-available.html @@ -468,7 +468,7 @@

응답

"data" : { "isPossible" : false, "point" : 200, - "createdAt" : "2024-01-25 03:40:17", + "createdAt" : "2024-01-26 22:18:12", "friendStatus" : 1 } } diff --git a/src/main/resources/static/docs/find-notice.html b/src/main/resources/static/docs/find-notice.html index 82199859..34871375 100644 --- a/src/main/resources/static/docs/find-notice.html +++ b/src/main/resources/static/docs/find-notice.html @@ -5,7 +5,7 @@ -공지 조회 (명세) +공지 조회 + + + +
+
+

친구 투표 전체 조회 (명세)

+
+
+

요청

+
+
+
GET /v2/vote/friend?page={}&type={} HTTP/1.1
+Authorization: Bearer your-access-token
+Content-Type: application-json
+
+
+
+

업데이트 예정 +- "type": "send" | null

+
+ ++++ + + + + + + +

type

조회할 쪽지 종류 (null → 모든쪽지, send→ 보낸쪽지)

+
+
+

응답

+
+
+
{
+  "status" : 200,
+  "message" : "투표 조회에 성공했습니다.",
+  "data" : {
+    "totalCount" : 1,
+    "friendVotes" : [ {
+            "id" : 1,
+			"senderId" : 1,
+			"senderName" : "name1",
+			"senderGender" : "MALE",
+			"senderYelloId" : "MALE",
+            "senderProfileImage": "imageUrl",
+			"receiverId" : 2,
+            "receiverName" : "name2",
+			"receiverGender" : "MALE",
+			"receiverYelloId" : "MALE",
+			"receiverProfileImage" : "test image",
+            "vote" : {
+                "nameHead" : "나는",
+                "nameFoot" : "와",
+                "keywordHead" : "멋진",
+                "keyword" : "test",
+                "keywordFoot" : "에서 놀고싶어"
+            },
+            "isHintUsed" : false,
+            "createdAt" : "0초 전"
+            "isUserSenderVote" : true
+    } ]
+  }
+}
+
+
+
+

필드 타입

+
+
+
    +
  • +

    "totalCount": Integer

    +
  • +
  • +

    "friendVotes": FriendVote[]

    +
  • +
  • +

    "isUserSenderVote" : Boolean (내가 보냈는지 여부)

    +
  • +
  • +

    FriendVote

    +
    +
      +
    • +

      "id": Long

      +
    • +
    • +

      "senderId" : Long

      +
    • +
    • +

      "senderName" : String

      +
    • +
    • +

      "senderYelloId" : String

      +
    • +
    • +

      "senderGender": "MALE" | "FEMALE"

      +
    • +
    • +

      "senderProfileImage" : String

      +
    • +
    • +

      "receiverId" : Long

      +
    • +
    • +

      "receiverName": String

      +
    • +
    • +

      "receiverYelloId" : String

      +
    • +
    • +

      "receiverGender": "MALE" | "FEMALE"

      +
    • +
    • +

      "receiverProfileImage": String

      +
    • +
    • +

      "vote": Vote

      +
    • +
    • +

      "isHintUsed": Boolean

      +
    • +
    • +

      "createdAt": "{0}초 전" | "{0}분 전" | "{0}시간 전" | "{0}일 전"

      +
    • +
    +
    +
  • +
  • +

    Vote

    +
    +
      +
    • +

      "nameHead": String

      +
    • +
    • +

      "nameFoot": String

      +
    • +
    • +

      "keywordHead": String

      +
    • +
    • +

      "keyword": String

      +
    • +
    • +

      "keywordFoot": String

      +
    • +
    +
    +
  • +
+
+
+
+

NOTE

+
+
    +
  • +

    모든 종류의 쪽지를 조회할 때 /api/v1/vote/friend?page=0 으로 요청해주세요

    +
    +
      +
    • +

      type= 을 명시하지 마세요

      +
    • +
    +
    +
  • +
  • +

    내가 보낸 쪽지를 조회할 때 /api/v1/vote/friend?page=0&type=send 으로 요청해주세요

    +
  • +
  • +

    senderGender 필드가 다른 API와 일관되지 못한점 미안해요 ㅠ

    +
  • +
+
+
+
+

CHANGELOG

+
+
    +
  • +

    2024.01.26 필드 명세 업데이트

    +
  • +
  • +

    2024.01.09 type 명세 업데이트

    +
  • +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/src/main/resources/static/docs/google.html b/src/main/resources/static/docs/google.html index b2e1908b..e9146061 100644 --- a/src/main/resources/static/docs/google.html +++ b/src/main/resources/static/docs/google.html @@ -481,7 +481,7 @@

응답

"message" : "구글 구독 결제 검증 및 반영에 성공하였습니다.", "data" : { "productId" : "productId", - "expiredAt" : "2024-01-26T22:18:02.473353" + "expiredAt" : "2024-01-26T22:41:37.086752" } } diff --git a/src/main/resources/static/docs/index.html b/src/main/resources/static/docs/index.html index 246cc595..5b0e3b2b 100644 --- a/src/main/resources/static/docs/index.html +++ b/src/main/resources/static/docs/index.html @@ -537,7 +537,7 @@

Vote API

내 투표 전체 조회하기

  • -

    ⬆️ 친구 투표 전체 조회하기, 2024-01-09

    +

    ⬆️ 친구 투표 전체 조회하기 (명세), 2024-01-09

  • 읽지 않은 쪽지 개수 조회하기

    @@ -632,7 +632,7 @@

    Notice API

    From 61d66d7aa14e9dd359a616ab327342c285b1fd63 Mon Sep 17 00:00:00 2001 From: hyeonjeongs Date: Sat, 27 Jan 2024 14:02:24 +0900 Subject: [PATCH 09/11] =?UTF-8?q?YEL-185=20[feat]=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/notice/dto/NoticeDataResponse.java | 4 ++-- .../repository/NoticeRepositoryImpl.java | 21 ++++++++++++------- .../response/UserSubscribeDetailResponse.java | 5 +++-- .../global/common/factory/TimeFactory.java | 14 +++++++------ .../global/common/util/ConstantUtil.java | 2 +- .../domain/notice/FakeNoticeRepository.java | 9 ++++++++ .../yello/server/util/TestDataEntityUtil.java | 7 +++++-- .../server/util/TestDataRepositoryUtil.java | 7 +++++-- 8 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java b/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java index 35a5ce73..9dbbc456 100644 --- a/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java +++ b/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java @@ -20,8 +20,8 @@ public static NoticeDataResponse of(Notice notice, Boolean isAvailable) { return NoticeDataResponse.builder() .imageUrl(notice.getImageUrl()) .redirectUrl(notice.getRedirectUrl()) - .startDate(toYearAndMonthFormattedString(notice.getStartDate().toLocalDateTime(), PLUS_BASIC_TIME)) - .endDate(toYearAndMonthFormattedString(notice.getEndDate().toLocalDateTime(), PLUS_BASIC_TIME)) + .startDate(toYearAndMonthFormattedString(notice.getStartDate().toLocalDateTime())) + .endDate(toYearAndMonthFormattedString(notice.getEndDate().toLocalDateTime())) .isAvailable(isAvailable) .build(); } diff --git a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java index 69ec529a..ea6fb173 100644 --- a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java +++ b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java @@ -1,15 +1,15 @@ package com.yello.server.domain.notice.repository; +import static com.yello.server.domain.notice.entity.QNotice.notice; + import com.querydsl.jpa.impl.JPAQueryFactory; import com.yello.server.domain.notice.entity.Notice; +import java.time.ZoneId; +import java.time.ZonedDateTime; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; - -import static com.yello.server.domain.notice.entity.QNotice.notice; - @Repository @RequiredArgsConstructor @Transactional(readOnly = true) @@ -20,15 +20,20 @@ public class NoticeRepositoryImpl implements NoticeRepository { @Override public Notice getTopNotice() { + ZoneId zoneId = ZoneId.of("Asia/Seoul"); + ZonedDateTime zonedDateTime = ZonedDateTime.now(zoneId); return jpaQueryFactory - .selectFrom(notice) - .orderBy(notice.endDate.desc()) - .fetchFirst(); + .selectFrom(notice) + .where(notice.isAvailable.eq(true) + .and(notice.startDate.loe(zonedDateTime)) + .and(notice.endDate.goe(zonedDateTime))) + .orderBy(notice.endDate.desc()) + .fetchFirst(); } @Override public Notice save(Notice notice) { - return null; + return noticeJpaRepository.save(notice); } } diff --git a/src/main/java/com/yello/server/domain/user/dto/response/UserSubscribeDetailResponse.java b/src/main/java/com/yello/server/domain/user/dto/response/UserSubscribeDetailResponse.java index a050f22b..03dbf109 100644 --- a/src/main/java/com/yello/server/domain/user/dto/response/UserSubscribeDetailResponse.java +++ b/src/main/java/com/yello/server/domain/user/dto/response/UserSubscribeDetailResponse.java @@ -1,7 +1,7 @@ package com.yello.server.domain.user.dto.response; import static com.yello.server.global.common.factory.TimeFactory.toYearAndMonthFormattedString; -import static com.yello.server.global.common.util.ConstantUtil.PLUS_SEVEN_TIME; +import static com.yello.server.global.common.util.ConstantUtil.SUBSCRIBE_DAYS; import com.yello.server.domain.purchase.entity.Purchase; import lombok.Builder; @@ -17,7 +17,8 @@ public static UserSubscribeDetailResponse of(Purchase purchase) { return UserSubscribeDetailResponse.builder() .id(purchase.getUser().getId()) .subscribe(purchase.getUser().getSubscribe().getIntial()) - .expiredDate(toYearAndMonthFormattedString(purchase.getUpdatedAt(), PLUS_SEVEN_TIME)) + .expiredDate( + toYearAndMonthFormattedString(purchase.getUpdatedAt().plusDays(SUBSCRIBE_DAYS))) .build(); } } diff --git a/src/main/java/com/yello/server/global/common/factory/TimeFactory.java b/src/main/java/com/yello/server/global/common/factory/TimeFactory.java index 952e11db..93102ccc 100644 --- a/src/main/java/com/yello/server/global/common/factory/TimeFactory.java +++ b/src/main/java/com/yello/server/global/common/factory/TimeFactory.java @@ -2,6 +2,7 @@ import java.time.Duration; import java.time.LocalDateTime; +import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -53,18 +54,19 @@ public static LocalDateTime minusTime(LocalDateTime localDateTime, int time) { return localDateTime.minusMinutes(time); } - public static String toYearAndMonthFormattedString(LocalDateTime localDateTime, int time) { + public static String toYearAndMonthFormattedString(LocalDateTime localDateTime) { if (localDateTime == null) { return ""; } - LocalDateTime dateTimePlusSevenDays = localDateTime.plusDays(time); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - return dateTimePlusSevenDays.format(dateTimeFormatter); + return localDateTime.format(dateTimeFormatter); } - public static Boolean compareNowAndEndData(ZonedDateTime localDateTime) { - ZonedDateTime now = ZonedDateTime.now(); - return now.isBefore(localDateTime); + public static Boolean compareNowAndEndData(ZonedDateTime zonedDateTime) { + ZoneId zoneId = ZoneId.of("Asia/Seoul"); + ZonedDateTime now = ZonedDateTime.now(zoneId); + + return now.isBefore(zonedDateTime); } } diff --git a/src/main/java/com/yello/server/global/common/util/ConstantUtil.java b/src/main/java/com/yello/server/global/common/util/ConstantUtil.java index ab76a259..c10af4d5 100644 --- a/src/main/java/com/yello/server/global/common/util/ConstantUtil.java +++ b/src/main/java/com/yello/server/global/common/util/ConstantUtil.java @@ -65,7 +65,7 @@ public class ConstantUtil { public static final int REFUND_TWO_TICKET = 2; public static final int REFUND_FIVE_TICKET = 5; public static final int NO_FRIEND_COUNT = 0; - public static final int PLUS_SEVEN_TIME = 7; + public static final int SUBSCRIBE_DAYS = 7; public static final int PLUS_BASIC_TIME = 0; diff --git a/src/test/java/com/yello/server/domain/notice/FakeNoticeRepository.java b/src/test/java/com/yello/server/domain/notice/FakeNoticeRepository.java index c8c72682..ab94b002 100644 --- a/src/test/java/com/yello/server/domain/notice/FakeNoticeRepository.java +++ b/src/test/java/com/yello/server/domain/notice/FakeNoticeRepository.java @@ -5,6 +5,7 @@ import com.yello.server.domain.notice.entity.Notice; import com.yello.server.domain.notice.exception.NoticeNotFoundException; import com.yello.server.domain.notice.repository.NoticeRepository; +import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.Comparator; @@ -17,7 +18,15 @@ public class FakeNoticeRepository implements NoticeRepository { @Override public Notice getTopNotice() { + ZoneId zoneId = ZoneId.of("Asia/Seoul"); + ZonedDateTime now = ZonedDateTime.now(zoneId); + return data.stream() + .filter(notice -> + notice.getIsAvailable().equals(true) && + !notice.getStartDate().isAfter(now) && + !notice.getEndDate().isBefore(now) + ) .sorted(Comparator.comparing(Notice::getEndDate).reversed()) .findFirst() .orElseThrow(() -> new NoticeNotFoundException(NOT_FOUND_NOTICE_EXCEPTION)); diff --git a/src/test/java/com/yello/server/util/TestDataEntityUtil.java b/src/test/java/com/yello/server/util/TestDataEntityUtil.java index 4ef9c077..209d6ab4 100644 --- a/src/test/java/com/yello/server/util/TestDataEntityUtil.java +++ b/src/test/java/com/yello/server/util/TestDataEntityUtil.java @@ -16,6 +16,7 @@ import com.yello.server.domain.user.entity.User; import com.yello.server.domain.vote.entity.Vote; import java.time.LocalDateTime; +import java.time.ZoneId; import java.time.ZonedDateTime; public class TestDataEntityUtil implements TestDataUtil { @@ -143,11 +144,13 @@ public Purchase generatePurchase(long index, User user) { @Override public Notice genereateNotice(long index) { + ZoneId zoneId = ZoneId.of("Asia/Seoul"); + ZonedDateTime now = ZonedDateTime.now(zoneId); return Notice.builder() .id(index) - .endDate(ZonedDateTime.now().minusDays(3)) + .endDate(now.plusDays(3)) .imageUrl("imageUrl") - .startDate(ZonedDateTime.now().minusDays(10)) + .startDate(now.minusDays(3)) .redirectUrl("redirectUrl") .isAvailable(true) .build(); diff --git a/src/test/java/com/yello/server/util/TestDataRepositoryUtil.java b/src/test/java/com/yello/server/util/TestDataRepositoryUtil.java index db4a965f..76666943 100644 --- a/src/test/java/com/yello/server/util/TestDataRepositoryUtil.java +++ b/src/test/java/com/yello/server/util/TestDataRepositoryUtil.java @@ -23,6 +23,7 @@ import com.yello.server.domain.vote.entity.Vote; import com.yello.server.domain.vote.repository.VoteRepository; import java.time.LocalDateTime; +import java.time.ZoneId; import java.time.ZonedDateTime; public class TestDataRepositoryUtil implements TestDataUtil { @@ -172,11 +173,13 @@ public Purchase generatePurchase(long index, User user) { @Override public Notice genereateNotice(long index) { + ZoneId zoneId = ZoneId.of("Asia/Seoul"); + ZonedDateTime now = ZonedDateTime.now(zoneId); return noticeRepository.save(Notice.builder() .id(index) - .endDate(ZonedDateTime.now().plusDays(3)) + .endDate(now.plusDays(3)) .imageUrl("imageUrl") - .startDate(ZonedDateTime.now().minusDays(4)) + .startDate(now.minusDays(3)) .redirectUrl("redirectUrl") .isAvailable(true) .build()); From 0bc5b14d4b2160bcfe5566bb6e578b8b33ad44fe Mon Sep 17 00:00:00 2001 From: hyeonjeongs Date: Sat, 27 Jan 2024 15:33:01 +0900 Subject: [PATCH 10/11] =?UTF-8?q?YEL-185=20[feat]=20notice=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/find-notice.adoc | 25 +++++++++++++ .../domain/notice/dto/NoticeDataResponse.java | 34 +++++++++-------- .../server/domain/notice/entity/Notice.java | 6 +++ .../notice/repository/NoticeRepository.java | 2 +- .../repository/NoticeRepositoryImpl.java | 8 ++-- .../domain/notice/service/NoticeService.java | 23 +++++++----- .../global/common/factory/TimeFactory.java | 1 + .../static/docs/check-vote-available.html | 2 +- .../static/docs/find-friend-votes.html | 37 ++----------------- .../resources/static/docs/find-notice.html | 8 ++-- src/main/resources/static/docs/google.html | 2 +- src/main/resources/static/docs/index.html | 5 ++- .../resources/static/docs/purchase-info.html | 2 +- .../domain/notice/FakeNoticeRepository.java | 8 ++-- .../yello/server/util/TestDataEntityUtil.java | 2 + .../server/util/TestDataRepositoryUtil.java | 2 + 16 files changed, 95 insertions(+), 72 deletions(-) diff --git a/src/docs/asciidoc/find-notice.adoc b/src/docs/asciidoc/find-notice.adoc index eceebdbc..0b6390a0 100644 --- a/src/docs/asciidoc/find-notice.adoc +++ b/src/docs/asciidoc/find-notice.adoc @@ -21,6 +21,31 @@ include::{snippets}/api/v1/notice/http-response.adoc[] * YYYY-MM-DD (ISO-8601) - "isAvailable": Boolean + +=== 주의 + +[http, json] + +*유효한 날짜의 공지가 존재하지 않는 경우* + +-> isAvailable은 false로 오고 날짜 제외한 나머지 값은 빈값으로 전달 + +---- +{ + "status": 200, + "message": "공지 조회에 성공하였습니다.", + "data": { + "imageUrl": "", + "redirectUrl": "", + "startDate": "2024-01-27", + "endDate": "2024-01-27", + "isAvailable": false, + "type": null, + "title": "" +} + +---- + === NOTE - 공지 정보를 조회하는 API입니다. diff --git a/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java b/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java index 9dbbc456..41e61948 100644 --- a/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java +++ b/src/main/java/com/yello/server/domain/notice/dto/NoticeDataResponse.java @@ -1,29 +1,31 @@ package com.yello.server.domain.notice.dto; +import static com.yello.server.global.common.factory.TimeFactory.toYearAndMonthFormattedString; + import com.yello.server.domain.notice.entity.Notice; import lombok.Builder; -import java.time.LocalDateTime; - -import static com.yello.server.global.common.factory.TimeFactory.toYearAndMonthFormattedString; -import static com.yello.server.global.common.util.ConstantUtil.PLUS_BASIC_TIME; - @Builder public record NoticeDataResponse( - String imageUrl, - String redirectUrl, - String startDate, - String endDate, - boolean isAvailable + String imageUrl, + String redirectUrl, + String startDate, + String endDate, + boolean isAvailable, + String type, + String title ) { + public static NoticeDataResponse of(Notice notice, Boolean isAvailable) { return NoticeDataResponse.builder() - .imageUrl(notice.getImageUrl()) - .redirectUrl(notice.getRedirectUrl()) - .startDate(toYearAndMonthFormattedString(notice.getStartDate().toLocalDateTime())) - .endDate(toYearAndMonthFormattedString(notice.getEndDate().toLocalDateTime())) - .isAvailable(isAvailable) - .build(); + .imageUrl(notice.getImageUrl()) + .redirectUrl(notice.getRedirectUrl()) + .startDate(toYearAndMonthFormattedString(notice.getStartDate().toLocalDateTime())) + .endDate(toYearAndMonthFormattedString(notice.getEndDate().toLocalDateTime())) + .isAvailable(isAvailable) + .type(notice.getType()) + .title(notice.getTitle()) + .build(); } } diff --git a/src/main/java/com/yello/server/domain/notice/entity/Notice.java b/src/main/java/com/yello/server/domain/notice/entity/Notice.java index 0e03a710..006af830 100644 --- a/src/main/java/com/yello/server/domain/notice/entity/Notice.java +++ b/src/main/java/com/yello/server/domain/notice/entity/Notice.java @@ -38,4 +38,10 @@ public class Notice extends AuditingTimeEntity { @Column(nullable = false) private Boolean isAvailable; + + @Column(nullable = false) + private String type; + + @Column(nullable = false) + private String title; } \ No newline at end of file diff --git a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepository.java b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepository.java index 25e6d87f..6fc64acd 100644 --- a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepository.java +++ b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepository.java @@ -6,7 +6,7 @@ public interface NoticeRepository { - Notice getTopNotice(); + Optional findTopNotice(); Notice save(Notice notice); } diff --git a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java index ea6fb173..7d3dae64 100644 --- a/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java +++ b/src/main/java/com/yello/server/domain/notice/repository/NoticeRepositoryImpl.java @@ -6,7 +6,9 @@ import com.yello.server.domain.notice.entity.Notice; import java.time.ZoneId; import java.time.ZonedDateTime; +import java.util.Optional; import lombok.RequiredArgsConstructor; +import org.aspectj.weaver.ast.Not; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; @@ -19,16 +21,16 @@ public class NoticeRepositoryImpl implements NoticeRepository { private final JPAQueryFactory jpaQueryFactory; @Override - public Notice getTopNotice() { + public Optional findTopNotice() { ZoneId zoneId = ZoneId.of("Asia/Seoul"); ZonedDateTime zonedDateTime = ZonedDateTime.now(zoneId); - return jpaQueryFactory + return Optional.ofNullable(jpaQueryFactory .selectFrom(notice) .where(notice.isAvailable.eq(true) .and(notice.startDate.loe(zonedDateTime)) .and(notice.endDate.goe(zonedDateTime))) .orderBy(notice.endDate.desc()) - .fetchFirst(); + .fetchFirst()); } @Override diff --git a/src/main/java/com/yello/server/domain/notice/service/NoticeService.java b/src/main/java/com/yello/server/domain/notice/service/NoticeService.java index 530f8048..9790a1a8 100644 --- a/src/main/java/com/yello/server/domain/notice/service/NoticeService.java +++ b/src/main/java/com/yello/server/domain/notice/service/NoticeService.java @@ -1,32 +1,37 @@ package com.yello.server.domain.notice.service; +import static com.yello.server.global.common.factory.TimeFactory.compareNowAndEndData; + import com.yello.server.domain.notice.dto.NoticeDataResponse; import com.yello.server.domain.notice.entity.Notice; import com.yello.server.domain.notice.repository.NoticeRepository; -import com.yello.server.domain.user.entity.User; import com.yello.server.domain.user.repository.UserRepository; +import java.time.ZoneId; +import java.time.ZonedDateTime; import lombok.Builder; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; -import java.util.Optional; - -import static com.yello.server.global.common.factory.TimeFactory.compareNowAndEndData; - @Service @Builder @RequiredArgsConstructor @Transactional(readOnly = true) public class NoticeService { + private final NoticeRepository noticeRepository; private final UserRepository userRepository; public NoticeDataResponse findNotice(Long userId) { - final User user = userRepository.getById(userId); - Notice noticeData = noticeRepository.getTopNotice(); - return NoticeDataResponse.of(noticeData, compareNowAndEndData(noticeData.getEndDate()) && noticeData.getIsAvailable()); + ZoneId zoneId = ZoneId.of("Asia/Seoul"); + ZonedDateTime now = ZonedDateTime.now(zoneId); + userRepository.findById(userId); + Notice noticeData = + noticeRepository.findTopNotice().orElseGet( + () -> Notice.builder().imageUrl("").redirectUrl("").title("").type("").endDate(now) + .startDate(now).isAvailable(false).build()); + return NoticeDataResponse.of(noticeData, + compareNowAndEndData(noticeData.getEndDate()) && noticeData.getIsAvailable()); } diff --git a/src/main/java/com/yello/server/global/common/factory/TimeFactory.java b/src/main/java/com/yello/server/global/common/factory/TimeFactory.java index 93102ccc..a860a13e 100644 --- a/src/main/java/com/yello/server/global/common/factory/TimeFactory.java +++ b/src/main/java/com/yello/server/global/common/factory/TimeFactory.java @@ -66,6 +66,7 @@ public static Boolean compareNowAndEndData(ZonedDateTime zonedDateTime) { ZoneId zoneId = ZoneId.of("Asia/Seoul"); ZonedDateTime now = ZonedDateTime.now(zoneId); + System.out.println(now + " sfsdfsd"); return now.isBefore(zonedDateTime); } diff --git a/src/main/resources/static/docs/check-vote-available.html b/src/main/resources/static/docs/check-vote-available.html index d66cb8f6..05de78e0 100644 --- a/src/main/resources/static/docs/check-vote-available.html +++ b/src/main/resources/static/docs/check-vote-available.html @@ -468,7 +468,7 @@

    응답

    "data" : { "isPossible" : false, "point" : 200, - "createdAt" : "2024-01-26 22:41:45", + "createdAt" : "2024-01-27 15:00:11", "friendStatus" : 1 } } diff --git a/src/main/resources/static/docs/find-friend-votes.html b/src/main/resources/static/docs/find-friend-votes.html index 4387f3c3..3ed670df 100644 --- a/src/main/resources/static/docs/find-friend-votes.html +++ b/src/main/resources/static/docs/find-friend-votes.html @@ -5,7 +5,7 @@ -친구 투표 전체 조회 (업데이트) +친구 투표 전체 조회 (최신버전 → v2 확인)