Skip to content

Commit

Permalink
Merge pull request #112 from moidot/feat/create-space-calendar
Browse files Browse the repository at this point in the history
스페이스 캘린더 일정 추가하기 API
  • Loading branch information
1000kkannoo authored Feb 7, 2024
2 parents c6ec102 + 786d84d commit 7bb9e69
Show file tree
Hide file tree
Showing 10 changed files with 433 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.moim.backend.domain.space.controller;

import com.moim.backend.domain.space.request.controller.CreateSpaceCalendarRequest;
import com.moim.backend.domain.space.response.space.CreateSpaceCalendarResponse;
import com.moim.backend.domain.space.service.SpaceCalendarService;
import com.moim.backend.global.common.CustomResponseEntity;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
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;

@RestController
@RequiredArgsConstructor
@RequestMapping("/space")
public class SpaceCalendarController {

private final SpaceCalendarService spaceCalendarService;

@PostMapping("/calendar")
public CustomResponseEntity<CreateSpaceCalendarResponse> createSpaceCalendar(
@RequestBody @Valid CreateSpaceCalendarRequest request
) {
return CustomResponseEntity.success(spaceCalendarService.createSpaceCalendar(request));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.moim.backend.domain.space.entity;

import com.moim.backend.domain.user.entity.Users;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

import static jakarta.persistence.FetchType.*;
import static jakarta.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PRIVATE;
import static lombok.AccessLevel.PROTECTED;

@Entity
@AllArgsConstructor(access = PRIVATE)
@NoArgsConstructor(access = PROTECTED)
@Getter
@Builder
public class SpaceCalendar {

@Id
@GeneratedValue(strategy = IDENTITY)
private Long spaceCalendarId;

@ManyToOne(fetch = LAZY)
@JoinColumn(name = "space_id")
private Space space;

@NotNull
private String scheduleName;

@NotNull
private LocalDateTime date;

@NotNull
private String dayOfWeek;

@NotNull
private String note;

private String locationName;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.moim.backend.domain.space.repository;

import com.moim.backend.domain.space.entity.SpaceCalendar;
import org.springframework.data.jpa.repository.JpaRepository;

public interface SpaceCalendarRepository extends JpaRepository<SpaceCalendar, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.moim.backend.domain.space.request.controller;

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.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;

import java.time.LocalDateTime;

@Getter
@AllArgsConstructor
@NoArgsConstructor
public class CreateSpaceCalendarRequest {

@NotNull
private Long spaceId;

@NotBlank(message = "스케줄명을 입력하지 않았습니다.")
@NotNull
private String scheduleName;

@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@NotNull(message = "날짜 및 시간을 입력하지 않았습니다.")
private LocalDateTime date;

@NotBlank(message = "메모를 입력하지 않았습니다.")
@NotNull
private String note;

private String locationName;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.moim.backend.domain.space.response.space;

import com.moim.backend.domain.space.entity.SpaceCalendar;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

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

import static lombok.AccessLevel.PRIVATE;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor(access = PRIVATE)
public class CreateSpaceCalendarResponse {
private Long spaceCalendarId;
private Long spaceId;
private String scheduleName;
private String date;
private String dayOfWeek;
private String note;
private String locationName;

public static CreateSpaceCalendarResponse response(SpaceCalendar spaceCalendar) {
return CreateSpaceCalendarResponse.builder()
.spaceCalendarId(spaceCalendar.getSpaceCalendarId())
.spaceId(spaceCalendar.getSpace().getSpaceId())
.scheduleName(spaceCalendar.getScheduleName())
.date(formatDate(spaceCalendar.getDate()))
.dayOfWeek(spaceCalendar.getDayOfWeek())
.note(spaceCalendar.getNote())
.locationName(spaceCalendar.getLocationName())
.build();
}

private static String formatDate(LocalDateTime date) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
return date.format(formatter);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.moim.backend.domain.space.service;

import com.moim.backend.domain.space.entity.Space;
import com.moim.backend.domain.space.entity.SpaceCalendar;
import com.moim.backend.domain.space.repository.SpaceCalendarRepository;
import com.moim.backend.domain.space.repository.SpaceRepository;
import com.moim.backend.domain.space.request.controller.CreateSpaceCalendarRequest;
import com.moim.backend.domain.space.response.space.CreateSpaceCalendarResponse;
import com.moim.backend.global.common.exception.CustomException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import static com.moim.backend.global.common.Result.NOT_FOUND_GROUP;
import static java.time.format.TextStyle.SHORT;
import static java.util.Locale.KOREAN;

@Service
@RequiredArgsConstructor
public class SpaceCalendarService {
private final SpaceCalendarRepository spaceCalendarRepository;
private final SpaceRepository spaceRepository;

public CreateSpaceCalendarResponse createSpaceCalendar(CreateSpaceCalendarRequest request) {
Space space = spaceRepository.findById(request.getSpaceId()).orElseThrow(
() -> new CustomException(NOT_FOUND_GROUP)
);

SpaceCalendar spaceCalendar = spaceCalendarRepository.save(SpaceCalendar.builder()
.space(space)
.scheduleName(request.getScheduleName())
.date(request.getDate())
.dayOfWeek(request.getDate().getDayOfWeek().getDisplayName(SHORT, KOREAN))
.note(request.getNote())
.locationName(request.getLocationName())
.build());

return CreateSpaceCalendarResponse.response(spaceCalendar);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.moim.backend.docs.space;

import com.epages.restdocs.apispec.ResourceSnippetParameters;
import com.moim.backend.RestDocsSupport;
import com.moim.backend.domain.space.controller.SpaceCalendarController;
import com.moim.backend.domain.space.request.controller.CreateSpaceCalendarRequest;
import com.moim.backend.domain.space.response.space.CreateSpaceCalendarResponse;
import com.moim.backend.domain.space.service.SpaceCalendarService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;

import java.time.LocalDateTime;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
import static org.springframework.restdocs.payload.JsonFieldType.*;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

public class SpaceCalendarControllerDocsTest extends RestDocsSupport {

private final SpaceCalendarService spaceCalendarService = mock(SpaceCalendarService.class);

@Override
protected Object initController() {
return new SpaceCalendarController(spaceCalendarService);
}

@DisplayName("모임 캘린더 일정 추가 API")
@Test
void createCalendar() throws Exception {
// given
LocalDateTime localDateTime = LocalDateTime.of(2024, 1, 2, 15, 37, 32);
CreateSpaceCalendarRequest request =
new CreateSpaceCalendarRequest(1L, "테스트 입니다", localDateTime, "테스트", "안산시 성포동");


given(spaceCalendarService.createSpaceCalendar(any(CreateSpaceCalendarRequest.class)))
.willReturn(
CreateSpaceCalendarResponse.builder()
.spaceCalendarId(1L)
.spaceId(1L)
.scheduleName("테스트 입니다")
.date("2024-02-07T15:36:32")
.dayOfWeek("수")
.note("안녕하세요")
.locationName("안산시 상록구 예술광장 1로")
.build());

ResourceSnippetParameters parameters = ResourceSnippetParameters.builder()
.tag("모임 캘린더 API")
.summary("모임 캘린더 생성 API")
.requestFields(
fieldWithPath("spaceId").type(NUMBER).description("스페이스 ID"),
fieldWithPath("scheduleName").type(STRING).description("스케줄명"),
fieldWithPath("date").type(ARRAY).description("형식 : yyyy-MM-dd'T'HH:mm:ss"),
fieldWithPath("note").type(STRING).description("메모"),
fieldWithPath("locationName").type(STRING).description("장소 이름"))
.responseFields(
fieldWithPath("code").type(NUMBER).description("상태 코드"),
fieldWithPath("message").type(STRING).description("상태 메세지"),
fieldWithPath("data.spaceCalendarId").type(NUMBER).description("개인 캘린더 ID"),
fieldWithPath("data.spaceId").type(NUMBER).description("유저 ID"),
fieldWithPath("data.scheduleName").type(STRING).description("스케줄명"),
fieldWithPath("data.date").type(STRING).description("날짜 및 시간 ex) '2024-01-24T15:36:15' "),
fieldWithPath("data.dayOfWeek").type(STRING).description("요일"),
fieldWithPath("data.note").type(STRING).description("메모"),
fieldWithPath("data.locationName").type(STRING).description("장소 이름"))
.build();

RestDocumentationResultHandler document =
documentHandler("create-space-calendar", prettyPrint(), prettyPrint(), parameters);

// when // then
mockMvc.perform(
RestDocumentationRequestBuilders.post("/space/calendar")
.header("Authorization", "JWT AccessToken")
.content(objectMapper.writeValueAsString(request))
.contentType(APPLICATION_JSON)
)
.andDo(print())
.andExpect(status().isOk())
.andDo(document);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.moim.backend.domain.bookmark.controller.BookmarkController;
import com.moim.backend.domain.space.controller.SpaceCalendarController;
import com.moim.backend.domain.spacevote.controller.VoteController;
import com.moim.backend.domain.space.controller.SpaceController;
import com.moim.backend.domain.user.controller.UserCalendarController;
Expand All @@ -23,7 +24,8 @@
UserController.class,
VoteController.class,
BookmarkController.class,
UserCalendarController.class
UserCalendarController.class,
SpaceCalendarController.class
}, excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {WebConfig.class, LoginInterceptor.class}
))
@AutoConfigureMockMvc(addFilters = false)
Expand All @@ -50,6 +52,9 @@ public abstract class ControllerTestSupport {
@MockBean
protected BookmarkController bookmarkController;

@MockBean
protected SpaceCalendarController spaceCalendarController;

@MockBean
protected LoginArgumentResolver loginArgumentResolver;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.moim.backend.domain.space.controller;

import com.moim.backend.domain.ControllerTestSupport;
import com.moim.backend.domain.space.request.controller.CreateSpaceCalendarRequest;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import java.time.LocalDateTime;

import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

class SpaceCalendarControllerTest extends ControllerTestSupport {
@DisplayName("모임 캘린더 일정 추가 API")
@Test
void createCalendar() throws Exception {
// given
LocalDateTime localDateTime = LocalDateTime.of(2024, 1, 2, 15, 37, 32);
CreateSpaceCalendarRequest request =
new CreateSpaceCalendarRequest(1L, "테스트 입니다", localDateTime, "테스트", "안산시 성포동");

// when // then
mockMvc.perform(
MockMvcRequestBuilders.post("/space/calendar")
.header("Authorization", "JWT AccessToken")
.content(objectMapper.writeValueAsString(request))
.contentType(APPLICATION_JSON)
)
.andDo(print())
.andExpect(status().isOk());
}
}
Loading

0 comments on commit 7bb9e69

Please sign in to comment.