From 608f83a3eb31849e857dadc58a43bb1874f0174e Mon Sep 17 00:00:00 2001 From: seyeon22222 <92151066+seyeon22222@users.noreply.github.com> Date: Mon, 30 Dec 2024 13:45:21 +0900 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20[Feature]=20Admin=20=EA=B3=B5?= =?UTF-8?q?=EC=9C=A0=EC=9D=BC=EC=A0=95=20=EC=A1=B0=ED=9A=8C=20API=20#1063?= =?UTF-8?q?=20(#1084)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PublicScheduleAdminRepository.java | 5 ++ .../PublicScheduleAdminController.java | 18 ++++++ .../response/PublicScheduleAdminResDto.java | 62 +++++++++++++++++++ .../service/PublicScheduleAdminService.java | 24 +++++++ .../admin/PublicScheduleAdminMockData.java | 52 +++++++++++++++- .../PublicScheduleAdminControllerTest.java | 61 ++++++++++++++++++ 6 files changed, 221 insertions(+), 1 deletion(-) diff --git a/gg-admin-repo/src/main/java/gg/admin/repo/calendar/PublicScheduleAdminRepository.java b/gg-admin-repo/src/main/java/gg/admin/repo/calendar/PublicScheduleAdminRepository.java index ff1d9715a..fa7932dc1 100644 --- a/gg-admin-repo/src/main/java/gg/admin/repo/calendar/PublicScheduleAdminRepository.java +++ b/gg-admin-repo/src/main/java/gg/admin/repo/calendar/PublicScheduleAdminRepository.java @@ -2,13 +2,18 @@ import java.util.List; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import gg.data.calendar.PublicSchedule; +import gg.data.calendar.type.DetailClassification; @Repository public interface PublicScheduleAdminRepository extends JpaRepository { List findByAuthor(String author); + + Page findAllByClassification(DetailClassification detailClassification, Pageable pageable); } diff --git a/gg-calendar-api/src/main/java/gg/calendar/api/admin/schedule/publicschedule/controller/PublicScheduleAdminController.java b/gg-calendar-api/src/main/java/gg/calendar/api/admin/schedule/publicschedule/controller/PublicScheduleAdminController.java index 7c5486c19..1c48773e0 100644 --- a/gg-calendar-api/src/main/java/gg/calendar/api/admin/schedule/publicschedule/controller/PublicScheduleAdminController.java +++ b/gg-calendar-api/src/main/java/gg/calendar/api/admin/schedule/publicschedule/controller/PublicScheduleAdminController.java @@ -4,13 +4,20 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import gg.calendar.api.admin.schedule.publicschedule.controller.request.PublicScheduleAdminCreateReqDto; +import gg.calendar.api.admin.schedule.publicschedule.controller.response.PublicScheduleAdminResDto; import gg.calendar.api.admin.schedule.publicschedule.service.PublicScheduleAdminService; +import gg.data.calendar.type.DetailClassification; +import gg.utils.dto.PageRequestDto; +import gg.utils.dto.PageResponseDto; import lombok.RequiredArgsConstructor; @RestController @@ -27,4 +34,15 @@ public ResponseEntity publicScheduleCreate( return ResponseEntity.status(HttpStatus.CREATED).build(); } + @GetMapping("/list/{detailClassification}") + public ResponseEntity> publicScheduleAdminClassificationList( + @PathVariable DetailClassification detailClassification, @ModelAttribute PageRequestDto pageRequestDto) { + int page = pageRequestDto.getPage(); + int size = pageRequestDto.getSize(); + + PageResponseDto pageResponseDto = publicScheduleAdminService.findAllByClassification( + detailClassification, page, size); + + return ResponseEntity.ok(pageResponseDto); + } } diff --git a/gg-calendar-api/src/main/java/gg/calendar/api/admin/schedule/publicschedule/controller/response/PublicScheduleAdminResDto.java b/gg-calendar-api/src/main/java/gg/calendar/api/admin/schedule/publicschedule/controller/response/PublicScheduleAdminResDto.java index b1556443c..b26e996d8 100644 --- a/gg-calendar-api/src/main/java/gg/calendar/api/admin/schedule/publicschedule/controller/response/PublicScheduleAdminResDto.java +++ b/gg-calendar-api/src/main/java/gg/calendar/api/admin/schedule/publicschedule/controller/response/PublicScheduleAdminResDto.java @@ -1,4 +1,66 @@ package gg.calendar.api.admin.schedule.publicschedule.controller.response; +import java.time.LocalDateTime; + +import gg.data.calendar.PublicSchedule; +import gg.data.calendar.type.DetailClassification; +import gg.data.calendar.type.EventTag; +import gg.data.calendar.type.JobTag; +import gg.data.calendar.type.ScheduleStatus; +import gg.data.calendar.type.TechTag; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class PublicScheduleAdminResDto { + private Long id; + + private DetailClassification classification; + + private EventTag eventTag; + + private JobTag jobTag; + + private TechTag techTag; + + private String author; + + private String title; + + private LocalDateTime startTime; + + private LocalDateTime endTime; + + private String link; + + private Integer sharedCount; + + private ScheduleStatus status; + + @Builder + public PublicScheduleAdminResDto(PublicSchedule publicSchedule) { + this.id = publicSchedule.getId(); + this.classification = publicSchedule.getClassification(); + this.eventTag = publicSchedule.getEventTag(); + this.jobTag = publicSchedule.getJobTag(); + this.techTag = publicSchedule.getTechTag(); + this.author = publicSchedule.getAuthor(); + this.title = publicSchedule.getTitle(); + this.startTime = publicSchedule.getStartTime(); + this.endTime = publicSchedule.getEndTime(); + this.link = publicSchedule.getLink(); + this.sharedCount = publicSchedule.getSharedCount(); + this.status = publicSchedule.getStatus(); + } + + @Override + public String toString() { + return "PublicScheduleAdminResDto{" + "id=" + id + ", classification=" + classification + ", eventTag=" + + eventTag + ", jobTag=" + jobTag + ", techTag=" + techTag + ", author='" + author + '\'' + ", title='" + + title + '\'' + ", startTime=" + startTime + ", endTime=" + endTime + ", link='" + link + '\'' + + ", sharedCount=" + sharedCount + ", status=" + status + '}'; + } } diff --git a/gg-calendar-api/src/main/java/gg/calendar/api/admin/schedule/publicschedule/service/PublicScheduleAdminService.java b/gg-calendar-api/src/main/java/gg/calendar/api/admin/schedule/publicschedule/service/PublicScheduleAdminService.java index f4b1d06b5..12a29d2bc 100644 --- a/gg-calendar-api/src/main/java/gg/calendar/api/admin/schedule/publicschedule/service/PublicScheduleAdminService.java +++ b/gg-calendar-api/src/main/java/gg/calendar/api/admin/schedule/publicschedule/service/PublicScheduleAdminService.java @@ -1,13 +1,22 @@ package gg.calendar.api.admin.schedule.publicschedule.service; import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import gg.admin.repo.calendar.PublicScheduleAdminRepository; import gg.calendar.api.admin.schedule.publicschedule.controller.request.PublicScheduleAdminCreateReqDto; +import gg.calendar.api.admin.schedule.publicschedule.controller.response.PublicScheduleAdminResDto; import gg.data.calendar.PublicSchedule; +import gg.data.calendar.type.DetailClassification; +import gg.utils.dto.PageResponseDto; import gg.utils.exception.ErrorCode; import gg.utils.exception.custom.CustomRuntimeException; import lombok.RequiredArgsConstructor; @@ -29,6 +38,21 @@ public void createPublicSchedule(PublicScheduleAdminCreateReqDto publicScheduleA publicScheduleAdminRepository.save(publicSchedule); } + public PageResponseDto findAllByClassification( + DetailClassification detailClassification, int page, int size) { + + Pageable pageable = PageRequest.of(page - 1, size, + Sort.by(Sort.Order.asc("status"), Sort.Order.asc("startTime"))); + + Page publicSchedules = publicScheduleAdminRepository.findAllByClassification( + detailClassification, pageable); + + List publicScheduleList = publicSchedules.stream() + .map(PublicScheduleAdminResDto::new) + .collect(Collectors.toList()); + return PageResponseDto.of(publicSchedules.getTotalElements(), publicScheduleList); + } + private void dateTimeErrorCheck(LocalDateTime startTime, LocalDateTime endTime) { if (startTime.isAfter(endTime)) { throw new CustomRuntimeException(ErrorCode.CALENDAR_BEFORE_DATE); diff --git a/gg-calendar-api/src/test/java/gg/calendar/api/admin/PublicScheduleAdminMockData.java b/gg-calendar-api/src/test/java/gg/calendar/api/admin/PublicScheduleAdminMockData.java index 6367d8da1..ba252e6a1 100644 --- a/gg-calendar-api/src/test/java/gg/calendar/api/admin/PublicScheduleAdminMockData.java +++ b/gg-calendar-api/src/test/java/gg/calendar/api/admin/PublicScheduleAdminMockData.java @@ -7,10 +7,11 @@ import org.springframework.stereotype.Component; import gg.admin.repo.calendar.PublicScheduleAdminRepository; -import gg.calendar.api.admin.schedule.publicschedule.controller.request.PublicScheduleAdminCreateReqDto; import gg.data.calendar.PublicSchedule; import gg.data.calendar.type.DetailClassification; import gg.data.calendar.type.EventTag; +import gg.data.calendar.type.JobTag; +import gg.data.calendar.type.ScheduleStatus; import lombok.RequiredArgsConstructor; @Component @@ -35,4 +36,53 @@ public PublicSchedule createPublicSchedule() { return publicScheduleAdminRepository.save(publicSchedule); } + public void createPublicScheduleEvent(int size) { + for (int i = 0; i < size; i++) { + PublicSchedule publicSchedule = PublicSchedule.builder() + .classification(DetailClassification.EVENT) + .eventTag(EventTag.JOB_FORUM) + .author("42GG") + .title("Job " + i) + .content("TEST JOB") + .link("https://gg.42seoul.kr") + .status(ScheduleStatus.ACTIVATE) + .startTime(LocalDateTime.now().plusDays(i)) + .endTime(LocalDateTime.now().plusDays(i + 10)) + .build(); + publicScheduleAdminRepository.save(publicSchedule); + } + } + + public void createPublicScheduleJob(int size) { + for (int i = 0; i < size; i++) { + PublicSchedule publicSchedule = PublicSchedule.builder() + .classification(DetailClassification.JOB_NOTICE) + .jobTag(JobTag.EXPERIENCED) + .author("42GG") + .title("Job " + i) + .content("TEST JOB") + .link("https://gg.42seoul.kr") + .status(ScheduleStatus.ACTIVATE) + .startTime(LocalDateTime.now().plusDays(i)) + .endTime(LocalDateTime.now().plusDays(i + 10)) + .build(); + publicScheduleAdminRepository.save(publicSchedule); + } + } + + public void createPublicSchedulePrivate(int size) { + for (int i = 0; i < size; i++) { + PublicSchedule publicSchedule = PublicSchedule.builder() + .classification(DetailClassification.PRIVATE_SCHEDULE) + .author("42GG") + .title("Private " + i) + .content("TEST Private") + .link("https://gg.42seoul.kr") + .status(ScheduleStatus.ACTIVATE) + .startTime(LocalDateTime.now().plusDays(i)) + .endTime(LocalDateTime.now().plusDays(i + 10)) + .build(); + publicScheduleAdminRepository.save(publicSchedule); + } + } } diff --git a/gg-calendar-api/src/test/java/gg/calendar/api/admin/schedule/publicschedule/controller/PublicScheduleAdminControllerTest.java b/gg-calendar-api/src/test/java/gg/calendar/api/admin/schedule/publicschedule/controller/PublicScheduleAdminControllerTest.java index 7278421ec..0bda1dbd5 100644 --- a/gg-calendar-api/src/test/java/gg/calendar/api/admin/schedule/publicschedule/controller/PublicScheduleAdminControllerTest.java +++ b/gg-calendar-api/src/test/java/gg/calendar/api/admin/schedule/publicschedule/controller/PublicScheduleAdminControllerTest.java @@ -7,6 +7,7 @@ import java.time.LocalDateTime; import java.util.List; +import java.util.stream.Stream; import javax.persistence.EntityManager; import javax.transaction.Transactional; @@ -15,16 +16,24 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import gg.admin.repo.calendar.PublicScheduleAdminRepository; import gg.calendar.api.admin.PublicScheduleAdminMockData; import gg.calendar.api.admin.schedule.publicschedule.controller.request.PublicScheduleAdminCreateReqDto; +import gg.calendar.api.admin.schedule.publicschedule.controller.response.PublicScheduleAdminResDto; import gg.calendar.api.admin.schedule.publicschedule.service.PublicScheduleAdminService; import gg.data.calendar.PublicSchedule; import gg.data.calendar.type.DetailClassification; @@ -34,6 +43,7 @@ import gg.data.user.User; import gg.utils.TestDataUtils; import gg.utils.annotation.IntegrationTest; +import gg.utils.dto.PageResponseDto; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -170,4 +180,55 @@ public void createPublicScheduleContentMax() throws Exception { .andExpect(status().isBadRequest()); } } + + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + @Nested + @DisplayName("Admin PublicSchedule 태그 조회 테스트") + class GetPublicScheduleAdminClassificationListTest { + + private Stream inputParams() { + return Stream.of(Arguments.of("EVENT", 2, 10), Arguments.of("JOB_NOTICE", 1, 10), + Arguments.of("PRIVATE_SCHEDULE", 1, 2)); + } + + @ParameterizedTest + @MethodSource("inputParams") + @DisplayName("Admin PublicSchedule 태그 조회 테스트 - 성공") + void getPublicScheduleAdminClassificationListTestSuccess(String tags, int page, int size) throws + Exception { + // given + publicScheduleAdminMockData.createPublicScheduleEvent(20); + publicScheduleAdminMockData.createPublicScheduleJob(10); + publicScheduleAdminMockData.createPublicSchedulePrivate(5); + + MultiValueMap params = new LinkedMultiValueMap<>(); + params.add("page", String.valueOf(page)); + params.add("size", String.valueOf(size)); + + // when + // multivalue map 을 통해서 값이 넘어옴 + String response = mockMvc.perform( + get("/admin/calendar/public/list/{detailClassification}", tags).header("Authorization", + "Bearer " + accessToken) + .params(params)) + .andDo(print()) + .andExpect(status().isOk()).andReturn().getResponse().getContentAsString(); + + // then + PageResponseDto pageResponseDto = objectMapper.readValue( + response, new TypeReference<>() { + }); + List result = pageResponseDto.getContent(); + + if (DetailClassification.valueOf(tags) == DetailClassification.PRIVATE_SCHEDULE) { + assertThat(result.size()).isEqualTo(2); + } else { + assertThat(result.size()).isEqualTo(10); + } + + for (PublicScheduleAdminResDto dto : result) { + System.out.println(dto.toString()); + } + } + } }