Skip to content

Commit

Permalink
Merge pull request #115 from moidot/feat/read-detail-calendar
Browse files Browse the repository at this point in the history
해당 날짜 일정 조회 API 구현
  • Loading branch information
1000kkannoo authored Feb 10, 2024
2 parents cb9e0d4 + ed32eb4 commit 0e7c8d4
Show file tree
Hide file tree
Showing 9 changed files with 273 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
import com.moim.backend.domain.user.entity.Users;
import com.moim.backend.domain.user.request.CreateUserCalendarRequest;
import com.moim.backend.domain.user.request.UserCalendarPageRequest;
import com.moim.backend.domain.user.request.UserDetailCalendarRequest;
import com.moim.backend.domain.user.response.CreateUserCalendarResponse;
import com.moim.backend.domain.user.response.UserCalendarPageResponse;
import com.moim.backend.domain.user.response.UserDetailCalendarResponse;
import com.moim.backend.domain.user.service.UserCalendarService;
import com.moim.backend.global.auth.Login;
import com.moim.backend.global.common.CustomResponseEntity;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/auth")
Expand All @@ -34,4 +38,12 @@ public CustomResponseEntity<UserCalendarPageResponse> readCalendar(
) {
return CustomResponseEntity.success(userCalendarService.readMyCalendar(user, request));
}

@GetMapping("/calendar/detail")
public CustomResponseEntity<List<UserDetailCalendarResponse>> readDetailCalendar(
@Login Users user,
@RequestBody @Valid UserDetailCalendarRequest request
) {
return CustomResponseEntity.success(userCalendarService.readDetailCalendar(user, request));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.moim.backend.domain.user.request;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import java.time.LocalDateTime;

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class UserDetailCalendarRequest {
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@NotNull(message = "날짜 및 시간을 입력하지 않았습니다.")
private LocalDateTime date;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.moim.backend.domain.user.response;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.moim.backend.domain.space.entity.Space;
import com.moim.backend.domain.space.entity.SpaceCalendar;
import com.moim.backend.domain.user.entity.UserCalendar;
import com.moim.backend.global.util.DateParser;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Builder
public class UserDetailCalendarResponse {
private String spaceName;
private String scheduleName;
private String date;
private String locationName;
private String color;

public static UserDetailCalendarResponse spaceCalendarResponse(Space space, SpaceCalendar spaceCalendar) {
return UserDetailCalendarResponse.builder()
.spaceName(space.getName())
.scheduleName(spaceCalendar.getScheduleName())
.date(DateParser.timeFormat(spaceCalendar.getDate()))
.locationName(spaceCalendar.getLocationName())
.color("space")
.build();
}

public static UserDetailCalendarResponse userCalendarResponse(UserCalendar userCalendar) {
return UserDetailCalendarResponse.builder()
.spaceName("")
.scheduleName(userCalendar.getScheduleName())
.date(DateParser.timeFormat(userCalendar.getDate()))
.locationName(userCalendar.getLocationName())
.color(userCalendar.getColor())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@
import com.moim.backend.domain.user.repository.UserCalendarRepository;
import com.moim.backend.domain.user.request.CreateUserCalendarRequest;
import com.moim.backend.domain.user.request.UserCalendarPageRequest;
import com.moim.backend.domain.user.request.UserDetailCalendarRequest;
import com.moim.backend.domain.user.response.CreateUserCalendarResponse;
import com.moim.backend.domain.user.response.UserCalendarPageResponse;
import jakarta.persistence.criteria.CriteriaBuilder;
import com.moim.backend.domain.user.response.UserDetailCalendarResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -122,4 +124,41 @@ private static LocalDateTime getEndDate(LocalDateTime startDate) {
return yearMonth.atEndOfMonth().atTime(23, 59, 59);
}

public List<UserDetailCalendarResponse> readDetailCalendar(Users user, UserDetailCalendarRequest request) {
List<UserDetailCalendarResponse> response = new ArrayList<>();
List<Participation> participations = participationRepository.findByUserId(user.getUserId());

// 해당 날짜의 개인 일정 추가
addMyCalendar(user, request, response);
// 해당 날짜의 스페이스 일정 추가
addSpaceCalendar(request, response, participations);

return response;
}

private void addMyCalendar(Users user, UserDetailCalendarRequest request, List<UserDetailCalendarResponse> response) {
LocalDateTime startDateTime = request.getDate();
LocalDateTime endDateTime = getEndDateTime(startDateTime);
List<UserCalendar> userCalendars = userCalendarRepository.findByUserAndDateBetween(user, startDateTime, endDateTime);
for (UserCalendar userCalendar : userCalendars) {
response.add(UserDetailCalendarResponse.userCalendarResponse(userCalendar));
}
}

private void addSpaceCalendar(UserDetailCalendarRequest request, List<UserDetailCalendarResponse> response, List<Participation> participations) {
for (Participation participation : participations) {
Space space = participation.getSpace();
LocalDateTime startDateTime = request.getDate();
LocalDateTime endDateTime = getEndDateTime(startDateTime);

List<SpaceCalendar> spaceCalendars = spaceCalendarRepository.findBySpaceAndDateBetween(space, startDateTime, endDateTime);
for (SpaceCalendar spaceCalendar : spaceCalendars) {
response.add(UserDetailCalendarResponse.spaceCalendarResponse(space, spaceCalendar));
}
}
}

private static LocalDateTime getEndDateTime(LocalDateTime startDateTime) {
return startDateTime.with(LocalTime.MAX);
}
}
13 changes: 13 additions & 0 deletions src/main/java/com/moim/backend/global/util/DateParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.moim.backend.global.util;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import static java.util.Locale.KOREAN;

public class DateParser {
public static String timeFormat(LocalDateTime date) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd(E) HH:mm", KOREAN);
return date.format(formatter);
}
}
66 changes: 66 additions & 0 deletions src/test/java/com/moim/backend/docs/user/UserCalendarDocsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import com.moim.backend.domain.user.controller.UserCalendarController;
import com.moim.backend.domain.user.request.CreateUserCalendarRequest;
import com.moim.backend.domain.user.request.UserCalendarPageRequest;
import com.moim.backend.domain.user.request.UserDetailCalendarRequest;
import com.moim.backend.domain.user.response.CreateUserCalendarResponse;
import com.moim.backend.domain.user.response.UserCalendarPageResponse;
import com.moim.backend.domain.user.response.UserDetailCalendarResponse;
import com.moim.backend.domain.user.service.UserCalendarService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -133,6 +135,10 @@ void readCalendar() throws Exception {
.tag("개인 캘린더 API")
.summary("내 캘린더 조회 API")
.description("요청시 date의 경우 배열 타입이 아닌 yyyy-MM-dd'T'HH:mm:ss 형식의 String으로 보내야 합니다")
.requestHeaders(
headerWithName("Authorization")
.description("Swagger 요청시 해당 입력칸이 아닌 우측 상단 자물쇠 " +
"또는 Authorize 버튼을 이용해 토큰을 넣어주세요"))
.requestFields(
fieldWithPath("date").type(ARRAY).description("형식(String) : yyyy-MM-dd'T'HH:mm:ss"))
.responseFields(
Expand Down Expand Up @@ -191,6 +197,66 @@ void readCalendar() throws Exception {
.andDo(document);
}

@DisplayName("해당 날짜 일정 조회 API")
@Test
void readDetailCalendar() throws Exception {
// given
UserDetailCalendarRequest request = new UserDetailCalendarRequest(LocalDateTime.of(2024, 2, 9, 0, 0, 0));

UserDetailCalendarResponse response1 = UserDetailCalendarResponse.builder()
.spaceName("")
.scheduleName("엄마랑 데이트")
.date("2024.02.09(금) 15:00")
.locationName("부천역 뉴코아 아웃백")
.color("RED")
.build();

UserDetailCalendarResponse response2 = UserDetailCalendarResponse.builder()
.spaceName("")
.scheduleName("모이닷 회의")
.date("2024.02.09(금) 15:00")
.locationName("부천역 뉴코아 아웃백")
.color("RED")
.build();

given(userCalendarService.readDetailCalendar(any(), any(UserDetailCalendarRequest.class)))
.willReturn(List.of(response1, response2));

ResourceSnippetParameters parameters = ResourceSnippetParameters.builder()
.tag("개인 캘린더 API")
.summary("해당 날짜 일정 조회 API")
.description("요청시 date의 경우 배열 타입이 아닌 yyyy-MM-dd'T'HH:mm:ss 형식의 String으로 보내야 합니다")
.requestHeaders(
headerWithName("Authorization")
.description("Swagger 요청시 해당 입력칸이 아닌 우측 상단 자물쇠 " +
"또는 Authorize 버튼을 이용해 토큰을 넣어주세요"))
.requestFields(
fieldWithPath("date").type(ARRAY).description("형식(String) : yyyy-MM-dd'T'HH:mm:ss"))
.responseFields(
fieldWithPath("code").type(NUMBER).description("상태 코드"),
fieldWithPath("message").type(STRING).description("상태 메세지"),
fieldWithPath("data[].spaceName").type(STRING).description("스페이스 이름(개인 일정인 경우 공백)"),
fieldWithPath("data[].scheduleName").type(STRING).description("스케줄명"),
fieldWithPath("data[].date").type(STRING).description("날짜"),
fieldWithPath("data[].locationName").type(STRING).description("장소 이름"),
fieldWithPath("data[].color").type(STRING).description("색상")
)
.build();

RestDocumentationResultHandler document = documentHandler("read-detail-calendar", prettyPrint(), prettyPrint(), parameters);

// when // then
mockMvc.perform(
RestDocumentationRequestBuilders.get("/auth/calendar/detail")
.header("Authorization", "JWT AccessToken")
.content(objectMapper.writeValueAsString(request))
.contentType(APPLICATION_JSON)
)
.andDo(print())
.andExpect(status().isOk())
.andDo(document);
}

private static Map<Integer, List<Schedule>> getDefaultResponse() {
Map<Integer, List<Schedule>> response = new HashMap<>();
for (int day = 1; day <= 31; day++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.moim.backend.domain.ControllerTestSupport;
import com.moim.backend.domain.user.request.CreateUserCalendarRequest;
import com.moim.backend.domain.user.request.UserCalendarPageRequest;
import com.moim.backend.domain.user.request.UserDetailCalendarRequest;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
Expand Down Expand Up @@ -32,7 +33,7 @@ void createCalendar() throws Exception {
.andExpect(status().isOk());
}

@DisplayName("개인 캘린더 일정 추가 API")
@DisplayName("캘린더 조회 API")
@Test
void readCalendar() throws Exception {
// given
Expand All @@ -48,4 +49,21 @@ void readCalendar() throws Exception {
.andDo(print())
.andExpect(status().isOk());
}

@DisplayName("해당 날짜 일정 조회 API")
@Test
void readDetailCalendar() throws Exception {
// given
UserDetailCalendarRequest request = new UserDetailCalendarRequest(LocalDateTime.of(2024, 2, 9, 0, 0, 0));

// when // then
mockMvc.perform(
MockMvcRequestBuilders.get("/auth/calendar/detail")
.header("Authorization", "JWT AccessToken")
.content(objectMapper.writeValueAsString(request))
.contentType(APPLICATION_JSON)
)
.andDo(print())
.andExpect(status().isOk());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
import com.moim.backend.domain.user.repository.UserRepository;
import com.moim.backend.domain.user.request.CreateUserCalendarRequest;
import com.moim.backend.domain.user.request.UserCalendarPageRequest;
import com.moim.backend.domain.user.request.UserDetailCalendarRequest;
import com.moim.backend.domain.user.response.CreateUserCalendarResponse;
import com.moim.backend.domain.user.response.UserCalendarPageResponse;
import com.moim.backend.domain.user.response.UserDetailCalendarResponse;
import jakarta.persistence.EntityManager;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -24,7 +27,9 @@

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

import static com.moim.backend.domain.space.entity.TransportationType.PERSONAL;
import static com.moim.backend.domain.space.entity.TransportationType.PUBLIC;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
Expand Down Expand Up @@ -52,6 +57,9 @@ class UserCalendarServiceTest {
@Autowired
private SpaceCalendarRepository spaceCalendarRepository;

@Autowired
private EntityManager em;

@DisplayName("유저가 자신의 일정을 하나 추가한다.")
@Test
void createUserCalendar() {
Expand Down Expand Up @@ -113,6 +121,31 @@ void readCalendar() {
);
}

@DisplayName("해당 날짜의 내 전체 일정을 확인한다.")
@Test
void readDetailCalendar() {
// given
Users user = savedUser("백[email protected]", "백1");
Space space = savedSpace(user.getUserId(), "스1");
savedParticipation(user, space, "백1", "test test", 123.123456, 37.123456, PERSONAL);

savedMyCalendar(user, LocalDateTime.of(2024, 2, 9, 0, 0, 0));
savedCalendar(space, LocalDateTime.of(2024, 2, 9, 23, 59, 59));

UserDetailCalendarRequest request = new UserDetailCalendarRequest(LocalDateTime.of(2024, 2, 9, 0, 0, 0));

// when
List<UserDetailCalendarResponse> response = userCalendarService.readDetailCalendar(user, request);

// then
assertThat(response)
.extracting("spaceName", "scheduleName", "date", "color")
.contains(
tuple("", "엄마랑 데이트", "2024.02.09(금) 00:00", "RED"),
tuple("스1", "모이닷 회의", "2024.02.09(금) 23:59", "space")
);
}


private void savedMyCalendar(Users user, LocalDateTime date) {
userCalendarRepository.save(
Expand Down
23 changes: 23 additions & 0 deletions src/test/java/com/moim/backend/global/util/DateParserTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.moim.backend.global.util;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;

import static org.assertj.core.api.Assertions.assertThat;

class DateParserTest {
@DisplayName("LocalDateTime 객체를 String 으로 파싱한다.")
@Test
void timeFormat() {
// given
LocalDateTime time = LocalDateTime.of(2024, 2, 9, 15, 30, 30);

// when
String str = DateParser.timeFormat(time);

// then
assertThat(str).isEqualTo("2024.02.09(금) 15:30");
}
}

0 comments on commit 0e7c8d4

Please sign in to comment.