diff --git a/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/AcademyCalendarCreateRequest.java b/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/AcademyCalendarCreateRequest.java index aab53a5a0..278f7455d 100644 --- a/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/AcademyCalendarCreateRequest.java +++ b/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/AcademyCalendarCreateRequest.java @@ -45,8 +45,8 @@ public static AcademyCalendarCreateParam to(AcademyCalendarCreateRequest request .stream() .map(lesson -> LessonScheduleCreateRequest.to(lesson)) .toList(), - LocalDate.parse(request.attendanceDate().getStartDateOfAttendance()), - LocalDate.parse(request.attendanceDate().getEndDateOfAttendance()), + LocalDate.parse(request.attendanceDate().startDateOfAttendance()), + LocalDate.parse(request.attendanceDate().endDateOfAttendance()), request.isAlarmed, request.childId, request.dashboardId, @@ -67,8 +67,8 @@ public record LessonScheduleCreateRequest( public static LessonScheduleParam to(LessonScheduleCreateRequest request) { return new LessonScheduleParam( DayOfWeek.valueOf(request.dayOfWeek()), - LocalTime.parse(request.lessonTime().getLessonStartTime()), - LocalTime.parse(request.lessonTime().getLessonEndTime()) + LocalTime.parse(request.lessonTime().lessonStartTime()), + LocalTime.parse(request.lessonTime().lessonEndTime()) ); } } diff --git a/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/AcademyCalendarUpdateRequest.java b/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/AcademyCalendarUpdateRequest.java index a0ef2de59..4ebb60399 100644 --- a/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/AcademyCalendarUpdateRequest.java +++ b/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/AcademyCalendarUpdateRequest.java @@ -48,8 +48,8 @@ public static AcademyCalendarUpdateParam to(AcademyCalendarUpdateRequest request .stream() .map(lesson -> LessonScheduleUpdateRequest.to(lesson)) .toList(), - LocalDate.parse(request.attendanceDate().getStartDateOfAttendance()), - LocalDate.parse(request.attendanceDate().getEndDateOfAttendance()), + LocalDate.parse(request.attendanceDate().startDateOfAttendance()), + LocalDate.parse(request.attendanceDate().endDateOfAttendance()), request.isAlarmed, memberId, request.childId, @@ -72,8 +72,8 @@ public record LessonScheduleUpdateRequest( public static LessonScheduleParam to(LessonScheduleUpdateRequest request) { return new LessonScheduleParam( DayOfWeek.valueOf(request.dayOfWeek()), - LocalTime.parse(request.lessonTime().getLessonStartTime()), - LocalTime.parse(request.lessonTime().getLessonEndTime()) + LocalTime.parse(request.lessonTime().lessonStartTime()), + LocalTime.parse(request.lessonTime().lessonEndTime()) ); } } diff --git a/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/AttendanceDate.java b/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/AttendanceDate.java index 746d64af3..3081f594c 100644 --- a/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/AttendanceDate.java +++ b/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/AttendanceDate.java @@ -1,20 +1,12 @@ package org.guzzing.studayserver.domain.calendar.controller.dto.request; +import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotBlank; import lombok.Getter; import org.guzzing.studayserver.domain.calendar.controller.dto.request.validation.ValidAttendanceDate; -@Getter @ValidAttendanceDate -public class AttendanceDate { - - private String startDateOfAttendance; - - private String endDateOfAttendance; - - @NotBlank - public AttendanceDate(String startDateOfAttendance, String endDateOfAttendance) { - this.startDateOfAttendance = startDateOfAttendance; - this.endDateOfAttendance = endDateOfAttendance; - } +public record AttendanceDate( + String startDateOfAttendance, + String endDateOfAttendance) { } diff --git a/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/LessonTime.java b/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/LessonTime.java index 6dabe5109..02800bc97 100644 --- a/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/LessonTime.java +++ b/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/LessonTime.java @@ -1,20 +1,12 @@ package org.guzzing.studayserver.domain.calendar.controller.dto.request; +import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotBlank; import lombok.Getter; import org.guzzing.studayserver.domain.calendar.controller.dto.request.validation.ValidLessonTime; -@Getter @ValidLessonTime -public class LessonTime { - - private String lessonStartTime; - - private String lessonEndTime; - - @NotBlank - public LessonTime(String lessonStartTime, String lessonEndTime) { - this.lessonStartTime = lessonStartTime; - this.lessonEndTime = lessonEndTime; - } +public record LessonTime( + String lessonStartTime, + String lessonEndTime) { } diff --git a/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/validation/AttendanceDateValidator.java b/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/validation/AttendanceDateValidator.java index 8c1f179c5..41627b0e8 100644 --- a/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/validation/AttendanceDateValidator.java +++ b/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/validation/AttendanceDateValidator.java @@ -21,8 +21,8 @@ public boolean isValid(AttendanceDate attendanceDate, ConstraintValidatorContext } try { - LocalDate startDate = LocalDate.parse(attendanceDate.getStartDateOfAttendance()); - LocalDate endDate = LocalDate.parse(attendanceDate.getEndDateOfAttendance()); + LocalDate startDate = LocalDate.parse(attendanceDate.startDateOfAttendance()); + LocalDate endDate = LocalDate.parse(attendanceDate.endDateOfAttendance()); if (endDate.isAfter(startDate.plusYears(MAX_DIFFERENCE_YEAR)) || endDate.isBefore(startDate)) { return false; diff --git a/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/validation/LessonTimeValidator.java b/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/validation/LessonTimeValidator.java index 0faa9aff4..03e13d664 100644 --- a/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/validation/LessonTimeValidator.java +++ b/src/main/java/org/guzzing/studayserver/domain/calendar/controller/dto/request/validation/LessonTimeValidator.java @@ -26,8 +26,8 @@ public boolean isValid(LessonTime lessonTime, ConstraintValidatorContext context } try { - LocalTime startTime = LocalTime.parse(lessonTime.getLessonStartTime(), TIME_FORMATTER); - LocalTime endTime = LocalTime.parse(lessonTime.getLessonEndTime(), TIME_FORMATTER); + LocalTime startTime = LocalTime.parse(lessonTime.lessonStartTime(), TIME_FORMATTER); + LocalTime endTime = LocalTime.parse(lessonTime.lessonEndTime(), TIME_FORMATTER); if (!isValidTimeRange(startTime, endTime, context) || !isStartTimeBeforeEndTime(startTime, endTime, context)) { diff --git a/src/test/java/org/guzzing/studayserver/docs/RestDocsSupport.java b/src/test/java/org/guzzing/studayserver/docs/RestDocsSupport.java new file mode 100644 index 000000000..3dcc48c5b --- /dev/null +++ b/src/test/java/org/guzzing/studayserver/docs/RestDocsSupport.java @@ -0,0 +1,38 @@ +package org.guzzing.studayserver.docs; + +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +@ExtendWith(RestDocumentationExtension.class) +public abstract class RestDocsSupport { + + protected MockMvc mockMvc; + protected ObjectMapper objectMapper; + + @BeforeEach + void setup(RestDocumentationContextProvider provider) { + JavaTimeModule javaTimeModule = new JavaTimeModule(); + javaTimeModule.addSerializer(LocalDateTimeSerializer.INSTANCE); + + objectMapper = new ObjectMapper() + .setSerializationInclusion(Include.NON_NULL) + .registerModule(javaTimeModule); + + mockMvc = MockMvcBuilders.standaloneSetup(initController()) + .setMessageConverters() + .apply(documentationConfiguration(provider)) + .build(); + } + + protected abstract Object initController(); +} diff --git a/src/test/java/org/guzzing/studayserver/domain/calendar/controller/AcademyCalendarControllerTest.java b/src/test/java/org/guzzing/studayserver/domain/calendar/controller/AcademyCalendarControllerTest.java index aea315b63..4e234441c 100644 --- a/src/test/java/org/guzzing/studayserver/domain/calendar/controller/AcademyCalendarControllerTest.java +++ b/src/test/java/org/guzzing/studayserver/domain/calendar/controller/AcademyCalendarControllerTest.java @@ -1,14 +1,14 @@ package org.guzzing.studayserver.domain.calendar.controller; +import static org.mockito.Mockito.mock; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import com.fasterxml.jackson.databind.ObjectMapper; import java.time.DayOfWeek; import java.util.List; import java.util.stream.Stream; +import org.guzzing.studayserver.docs.RestDocsSupport; import org.guzzing.studayserver.domain.calendar.controller.dto.request.AcademyCalendarCreateRequest; import org.guzzing.studayserver.domain.calendar.controller.dto.request.AcademyCalendarUpdateRequest; import org.guzzing.studayserver.domain.calendar.controller.dto.request.AttendanceDate; @@ -16,59 +16,47 @@ import org.guzzing.studayserver.domain.calendar.facade.AcademyCalendarFacade; import org.guzzing.studayserver.domain.calendar.model.Periodicity; import org.guzzing.studayserver.domain.calendar.service.AcademyCalendarService; -import org.guzzing.studayserver.testutil.WithMockCustomOAuth2LoginUser; import org.guzzing.studayserver.testutil.fixture.academycalender.AcademyCalenderFixture; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; -@WebMvcTest(AcademyCalendarController.class) -class AcademyCalendarControllerTest { +class AcademyCalendarControllerTest extends RestDocsSupport { - @Autowired - private MockMvc mvc; - - @Autowired - private ObjectMapper objectMapper; - - @MockBean private AcademyCalendarService academyCalendarService; - - @MockBean private AcademyCalendarFacade academyCalendarFacade; + @Override + protected Object initController() { + academyCalendarService = mock(AcademyCalendarService.class); + academyCalendarFacade = mock(AcademyCalendarFacade.class); + return new AcademyCalendarController(academyCalendarService, academyCalendarFacade); + } + @DisplayName(" 예외가 발생하는 상황을 검증한다.") @Nested class ThrowException { @DisplayName("스케줄 생성할 때 요청값에 대해 검증한다.") - @WithMockCustomOAuth2LoginUser @ParameterizedTest @MethodSource("provideInvalidCreateRequests") void createAcademyCalendar(AcademyCalendarCreateRequest academyCalendarCreateRequest) throws Exception { //Then - mvc.perform(post("/academy-schedules") + mockMvc.perform(post("/academy-schedules") .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(academyCalendarCreateRequest)) - .with(csrf())) + .content(objectMapper.writeValueAsString(academyCalendarCreateRequest))) .andExpect(status().isBadRequest()); } @DisplayName("스케줄 수정할 때 요청값에 대해 검증한다.") - @WithMockCustomOAuth2LoginUser @ParameterizedTest @MethodSource("provideInvalidUpdateRequests") void updateSchedule(AcademyCalendarUpdateRequest academyCalendarUpdateRequest) throws Exception { - mvc.perform(put("/academy-schedules") + mockMvc.perform(put("/academy-schedules") .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(academyCalendarUpdateRequest)) - .with(csrf())) + .content(objectMapper.writeValueAsString(academyCalendarUpdateRequest))) .andExpect(status().isBadRequest()); } diff --git a/src/test/java/org/guzzing/studayserver/domain/child/controller/ChildRestControllerTest.java b/src/test/java/org/guzzing/studayserver/domain/child/controller/ChildRestControllerTest.java index eddfc0c69..07de9e04c 100644 --- a/src/test/java/org/guzzing/studayserver/domain/child/controller/ChildRestControllerTest.java +++ b/src/test/java/org/guzzing/studayserver/domain/child/controller/ChildRestControllerTest.java @@ -6,6 +6,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; @@ -24,11 +25,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.epages.restdocs.apispec.ResourceSnippetParameters; -import com.fasterxml.jackson.databind.ObjectMapper; import java.time.LocalDate; import java.time.LocalTime; import java.util.List; import java.util.stream.Stream; +import org.guzzing.studayserver.docs.RestDocsSupport; import org.guzzing.studayserver.domain.child.controller.request.ChildCreateRequest; import org.guzzing.studayserver.domain.child.controller.request.ChildModifyRequest; import org.guzzing.studayserver.domain.child.controller.response.ChildrenFindResponse; @@ -37,7 +38,6 @@ import org.guzzing.studayserver.domain.child.service.ChildWithScheduleResult; import org.guzzing.studayserver.domain.child.service.param.ChildCreateParam; import org.guzzing.studayserver.domain.child.service.result.ChildProfileImagePatchResult; -import org.guzzing.studayserver.testutil.WithMockCustomOAuth2LoginUser; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -45,43 +45,31 @@ 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.restdocs.AutoConfigureRestDocs; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; import org.springframework.mock.web.MockMultipartFile; import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; -import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.web.multipart.MultipartFile; -@WebMvcTest(ChildRestController.class) -@AutoConfigureRestDocs -@AutoConfigureMockMvc(addFilters = false) -class ChildRestControllerTest { +class ChildRestControllerTest extends RestDocsSupport { private static final String TAG = "아이 API"; - @Autowired - private MockMvc mockMvc; - - @MockBean private ChildService childService; - - @MockBean private ChildFacade childFacade; - @Autowired - private ObjectMapper objectMapper; + @Override + protected Object initController() { + childService = mock(ChildService.class); + childFacade = mock(ChildFacade.class); + return new ChildRestController(childService, childFacade); + } @Nested class Create { @DisplayName("아이 생성시 정상 값이면 OK를 반환한다.") @Test - @WithMockCustomOAuth2LoginUser(memberId = 1L) void statusIsOk() throws Exception { // Given ChildCreateRequest request = new ChildCreateRequest("childName1", "초등학교 1학년"); @@ -100,7 +88,6 @@ void statusIsOk() throws Exception { @DisplayName("아이 생성시 잘못된 요청은 400에러를 반환한다.") @ParameterizedTest - @WithMockCustomOAuth2LoginUser(memberId = 1L) @MethodSource("provideInvalidRequests") void statusIsBadRequest(ChildCreateRequest invalidRequest) throws Exception { // Then @@ -126,7 +113,6 @@ private static Stream provideInvalidRequests() { } @DisplayName("멤버에 할당된 아이들의 정보를 반환한다.") - @WithMockCustomOAuth2LoginUser(memberId = 1L) @Test void findChildren_success() throws Exception { // Given @@ -149,7 +135,6 @@ void findChildren_success() throws Exception { } @DisplayName("아이를 삭제한다.") - @WithMockCustomOAuth2LoginUser() @Test void delete_success() throws Exception { // Given @@ -164,7 +149,6 @@ void delete_success() throws Exception { class modify { @DisplayName("아이의 정보를 수정한다.") - @WithMockCustomOAuth2LoginUser(memberId = 1L) @Test void success() throws Exception { // Given @@ -183,7 +167,6 @@ void success() throws Exception { } @DisplayName("잘못된 요청이 들어오면 예외를 발생시킨다.") - @WithMockCustomOAuth2LoginUser() @ParameterizedTest @MethodSource("provideInvalidRequests") void givenInvalidRequest_throwsException(ChildModifyRequest invalidRequest) throws Exception { diff --git a/src/test/java/org/guzzing/studayserver/domain/member/controller/MemberRestControllerTest.java b/src/test/java/org/guzzing/studayserver/domain/member/controller/MemberRestControllerTest.java index 74567de28..165c0dadf 100644 --- a/src/test/java/org/guzzing/studayserver/domain/member/controller/MemberRestControllerTest.java +++ b/src/test/java/org/guzzing/studayserver/domain/member/controller/MemberRestControllerTest.java @@ -2,6 +2,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; @@ -11,6 +12,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; import java.util.stream.Stream; +import org.guzzing.studayserver.docs.RestDocsSupport; import org.guzzing.studayserver.domain.child.controller.request.ChildCreateRequest; import org.guzzing.studayserver.domain.member.controller.request.MemberRegisterRequest; import org.guzzing.studayserver.domain.member.service.MemberFacade; @@ -33,27 +35,23 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -@WebMvcTest(MemberRestController.class) -@AutoConfigureMockMvc(addFilters = false) -class MemberRestControllerTest { +class MemberRestControllerTest extends RestDocsSupport { - @Autowired - private MockMvc mockMvc; - - @MockBean private MemberService memberService; - @MockBean private MemberFacade memberFacade; - @Autowired - private ObjectMapper objectMapper; + @Override + protected Object initController() { + memberService = mock(MemberService.class); + memberFacade = mock(MemberFacade.class); + return new MemberRestController(memberService, memberFacade); + } @Nested class Register { @DisplayName("멤버 등록시 정상 값이면 OK를 반환한다.") @Test - @WithMockCustomOAuth2LoginUser(memberId = 1L) void statusIsOk() throws Exception { // Given MemberRegisterRequest request = new MemberRegisterRequest("nickname", "email@example.com", List.of( @@ -120,23 +118,6 @@ private static Stream provideInvalidRequests() { class getInformation { @Test - @WithMockCustomOAuth2LoginUser(memberId = 999L) - @DisplayName("멤버가 존재하지 않는다면 예외를 발생시킨다.") - void whenMemberIdDoesNotExist_shouldThrowException() throws Exception { - // Given - Long nonExistentMemberId = 999L; - given(memberService.getById(nonExistentMemberId)).willThrow(new IllegalArgumentException()); - - // When & Then - mockMvc.perform(get("/members") - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON) - .param("memberId", nonExistentMemberId.toString())) - .andExpect(status().isBadRequest()); - } - - @Test - @WithMockCustomOAuth2LoginUser(memberId = 1L) @DisplayName("멤버가 존재한다면 상세 정보를 반환한다.") void whenMemberIdExists_shouldReturnMemberInformation() throws Exception { // Given