From f2e7fc813bbb2ba8441a9ce515b62ba77bbfbfac Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 20 Sep 2023 16:28:38 +0900 Subject: [PATCH 01/31] =?UTF-8?q?feat:=20docs=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiary/support/docs/ApiDocumentUtils.java | 19 ++++++ .../support/docs/RestDocsConfiguration.java | 21 +++++++ .../aiary/support/docs/RestDocumentTest.java | 61 +++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 src/test/java/com/aiary/aiary/support/docs/ApiDocumentUtils.java create mode 100644 src/test/java/com/aiary/aiary/support/docs/RestDocsConfiguration.java create mode 100644 src/test/java/com/aiary/aiary/support/docs/RestDocumentTest.java diff --git a/src/test/java/com/aiary/aiary/support/docs/ApiDocumentUtils.java b/src/test/java/com/aiary/aiary/support/docs/ApiDocumentUtils.java new file mode 100644 index 0000000..103de41 --- /dev/null +++ b/src/test/java/com/aiary/aiary/support/docs/ApiDocumentUtils.java @@ -0,0 +1,19 @@ +package com.aiary.aiary.support.docs; + +import org.springframework.restdocs.operation.preprocess.OperationRequestPreprocessor; +import org.springframework.restdocs.operation.preprocess.OperationResponsePreprocessor; + +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +public interface ApiDocumentUtils { + + // OperationRequestPreprocessor 는 API 문서화를 위해 요청에 대한 사전처리를 수행 + // prettyPrint() 메서드는 요청/응답을 보기 좋게 만듬. + static OperationRequestPreprocessor getDocumentRequest() { + return preprocessRequest(prettyPrint()); + } + + // OperationResponsePreprocessor 는 API 문서화를 위해 응답에 대한 사전처리를 수행 + static OperationResponsePreprocessor getDocumentResponse() { + return preprocessResponse(prettyPrint()); + } +} diff --git a/src/test/java/com/aiary/aiary/support/docs/RestDocsConfiguration.java b/src/test/java/com/aiary/aiary/support/docs/RestDocsConfiguration.java new file mode 100644 index 0000000..d2c930f --- /dev/null +++ b/src/test/java/com/aiary/aiary/support/docs/RestDocsConfiguration.java @@ -0,0 +1,21 @@ +package com.aiary.aiary.support.docs; + +import org.springframework.boot.test.autoconfigure.restdocs.RestDocsMockMvcConfigurationCustomizer; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; + +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; + +@TestConfiguration +public class RestDocsConfiguration { + + // Spring Rest Docs + MockMvc 함께 사용을 위한 빈 설정 + @Bean + public RestDocsMockMvcConfigurationCustomizer restDocsMockMvcConfigurationCustomizer() { + return configurer -> + configurer + .operationPreprocessors() + .withRequestDefaults(prettyPrint()) + .withResponseDefaults(prettyPrint()); + } +} \ No newline at end of file diff --git a/src/test/java/com/aiary/aiary/support/docs/RestDocumentTest.java b/src/test/java/com/aiary/aiary/support/docs/RestDocumentTest.java new file mode 100644 index 0000000..c752b86 --- /dev/null +++ b/src/test/java/com/aiary/aiary/support/docs/RestDocumentTest.java @@ -0,0 +1,61 @@ +package com.aiary.aiary.support.docs; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +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.Import; +import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.filter.CharacterEncodingFilter; + +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +@ExtendWith({RestDocumentationExtension.class, SpringExtension.class}) +@Import(RestDocsConfiguration.class) +@AutoConfigureRestDocs +@WebMvcTest +public abstract class RestDocumentTest { + + @Autowired + private ObjectMapper objectMapper; + protected MockMvc mockMvc; + + /* + * MockMvc + * -> 웹 어플리케이션의 웹 계층을 테스트 하기 위해 실제 HTTP 서버를 구동하지 않아도 되므로 테스트 속도를 향상시키고 + * 의존성을 줄일 수 있다. (테스트 중 외부 리소스에 독립적으로 테스트 수행가능) + * */ + @MockBean + private JpaMetamodelMappingContext jpaMetamodelMappingContext; + + protected String toRequestBody(Object value) throws JsonProcessingException { + return objectMapper.writeValueAsString(value); + } + + /* + * 1. @BeforeEach + * -> 각 테스트 메서드가 실행되기전에 수행되는 초기화 메서드 + * */ + @BeforeEach + public void setupMockMvc( + WebApplicationContext ctx, + RestDocumentationContextProvider restDocumentationContextProvider) { + mockMvc = + MockMvcBuilders.webAppContextSetup(ctx) + .apply(documentationConfiguration(restDocumentationContextProvider)) + .addFilter(new CharacterEncodingFilter("UTF-8", true)) + .alwaysDo(print()) + .build(); + } +} From 8282976404764bd17601e51912b9aed568da9960 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 20 Sep 2023 16:29:38 +0900 Subject: [PATCH 02/31] =?UTF-8?q?chore:=20docs/test=20=EC=9D=98=EC=A1=B4?= =?UTF-8?q?=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index da538b0..9f9993d 100644 --- a/build.gradle +++ b/build.gradle @@ -2,6 +2,7 @@ plugins { id 'java' id 'org.springframework.boot' version '2.7.14-SNAPSHOT' id 'io.spring.dependency-management' version '1.0.15.RELEASE' + id "org.asciidoctor.jvm.convert" version "3.3.2" } group = 'com.aiary' @@ -11,12 +12,6 @@ java { sourceCompatibility = '11' } -configurations { - compileOnly { - extendsFrom annotationProcessor - } -} - repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } @@ -40,10 +35,41 @@ dependencies { compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' + + // test testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.mockito:mockito-core:4.8.0' + testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' + testImplementation 'org.springframework.restdocs:spring-restdocs-asciidoctor' } tasks.named('test') { useJUnitPlatform() } + +// 변수 선언 +ext { + snippetsDir = file('build/generated-snippets') +} + +// bootjar과 관련된 설정이며, 스니펫을 이용해 문서 작성 후, +// build - docs - asciidoc 하위에 생기는 html 파일을 static/docs로 복사해줍니다. +bootJar { + dependsOn asciidoctor + from("${asciidoctor.outputDir}/html5") + into 'static/docs' +} + +asciidoctor { + inputs.dir snippetsDir + dependsOn test +} + +configurations { + asciidoctorExtensions + compileOnly { + extendsFrom annotationProcessor + } +} + From 279e28821c5decd39be54991908f8b745596db0e Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 20 Sep 2023 16:29:54 +0900 Subject: [PATCH 03/31] =?UTF-8?q?feat:=20DatabaseTest=20=EC=96=B4=EB=85=B8?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiary/support/database/DatabaseTest.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/test/java/com/aiary/aiary/support/database/DatabaseTest.java diff --git a/src/test/java/com/aiary/aiary/support/database/DatabaseTest.java b/src/test/java/com/aiary/aiary/support/database/DatabaseTest.java new file mode 100644 index 0000000..5bffc08 --- /dev/null +++ b/src/test/java/com/aiary/aiary/support/database/DatabaseTest.java @@ -0,0 +1,18 @@ +package com.aiary.aiary.support.database; + +import com.aiary.aiary.support.config.TestProfile; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +import javax.transaction.Transactional; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Transactional +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) +@ActiveProfiles(TestProfile.TEST) +public @interface DatabaseTest {} From d51047f1f16798b8f20cfc66aec49a318b9e0fa6 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 20 Sep 2023 16:30:31 +0900 Subject: [PATCH 04/31] =?UTF-8?q?feat:=20UserFixture=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiary/support/fixture/UserFixture.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/test/java/com/aiary/aiary/support/fixture/UserFixture.java diff --git a/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java b/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java new file mode 100644 index 0000000..cb69090 --- /dev/null +++ b/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java @@ -0,0 +1,21 @@ +package com.aiary.aiary.support.fixture; + +import com.aiary.aiary.domain.user.entity.Role; +import com.aiary.aiary.domain.user.entity.User; +import com.aiary.aiary.domain.user.entity.UserDetail; + +public class UserFixture { + + public static final User TEST_USER = User.builder() + .email("test@gmail.com") + .password("Test012@") + .nickname("테스트유저") + .role(Role.USER) + .build(); + + public static final UserDetail TEST_USERDETAIL = UserDetail.builder() + .user(TEST_USER) + .build(); + + +} From bf1b812dd6adbcd6a37d2c42573d4e7238817875 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 20 Sep 2023 16:30:44 +0900 Subject: [PATCH 05/31] =?UTF-8?q?feat:=20DiaryFixture=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiary/support/fixture/DiaryFixture.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java diff --git a/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java b/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java new file mode 100644 index 0000000..a98cc0a --- /dev/null +++ b/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java @@ -0,0 +1,28 @@ +package com.aiary.aiary.support.fixture; + +import com.aiary.aiary.domain.diary.dto.request.DiaryCreateReq; +import com.aiary.aiary.domain.diary.entity.Diary; +import com.aiary.aiary.domain.diary.entity.Weather; + +import java.time.LocalDate; + +public class DiaryFixture { + + public static final Diary TEST_DIARY = Diary.builder() + .title("일기 제목") + .weather(Weather.SUNNY) + .emoji("\uD83D\uDCAA") + .contents("일기 내용") + .drawingUrl("url") + .diaryDate(LocalDate.of(2023,9,19)) + .user(UserFixture.TEST_USER) + .build(); + + public static final DiaryCreateReq TEST_DIARY_CREATE_REQ = DiaryCreateReq.builder() + .title("일기 제목") + .weather("SUNNY") + .emoji("\uD83D\uDCAA") + .contents("일기 내용") + .diaryDate(LocalDate.of(2023,9,19)) + .build(); +} From 8358b661ba68ec1a243a4ae1e43165c89b4ca9bd Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 20 Sep 2023 16:31:04 +0900 Subject: [PATCH 06/31] =?UTF-8?q?feat:=20TestProfile=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/aiary/aiary/support/config/TestProfile.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/test/java/com/aiary/aiary/support/config/TestProfile.java diff --git a/src/test/java/com/aiary/aiary/support/config/TestProfile.java b/src/test/java/com/aiary/aiary/support/config/TestProfile.java new file mode 100644 index 0000000..1258ef5 --- /dev/null +++ b/src/test/java/com/aiary/aiary/support/config/TestProfile.java @@ -0,0 +1,5 @@ +package com.aiary.aiary.support.config; + +public interface TestProfile { + String TEST = "test"; +} \ No newline at end of file From 884aec359c92c58cb1caf7d2b0fb523dd43143de Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 20 Sep 2023 16:31:16 +0900 Subject: [PATCH 07/31] =?UTF-8?q?refactor:=20DiaryCreateReq=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiary/aiary/domain/diary/dto/request/DiaryCreateReq.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/aiary/aiary/domain/diary/dto/request/DiaryCreateReq.java b/src/main/java/com/aiary/aiary/domain/diary/dto/request/DiaryCreateReq.java index 4707da6..5157b90 100644 --- a/src/main/java/com/aiary/aiary/domain/diary/dto/request/DiaryCreateReq.java +++ b/src/main/java/com/aiary/aiary/domain/diary/dto/request/DiaryCreateReq.java @@ -8,7 +8,9 @@ import java.time.LocalDate; @Getter +@Builder @NoArgsConstructor(access = AccessLevel.PRIVATE) +@AllArgsConstructor(access = AccessLevel.PRIVATE) @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) public class DiaryCreateReq { From 7953327b6fa964a8015d30845c85964ad2381d40 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 20 Sep 2023 16:31:42 +0900 Subject: [PATCH 08/31] =?UTF-8?q?test:=20=EC=9D=BC=EA=B8=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9D=84=20=ED=99=95=EC=9D=B8=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diary/service/DiaryServiceTest.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java diff --git a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java new file mode 100644 index 0000000..4e4a3b1 --- /dev/null +++ b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java @@ -0,0 +1,57 @@ +package com.aiary.aiary.domain.diary.service; + +import com.aiary.aiary.domain.diary.dto.request.DiaryCreateReq; +import com.aiary.aiary.domain.diary.entity.Diary; +import com.aiary.aiary.domain.diary.repository.DiaryRepository; +import com.aiary.aiary.domain.user.entity.UserDetail; +import com.aiary.aiary.domain.user.repository.UserRepository; +import com.aiary.aiary.support.database.DatabaseTest; +import com.aiary.aiary.support.fixture.DiaryFixture; +import com.aiary.aiary.support.fixture.UserFixture; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.assertj.core.api.Assertions.*; +@DatabaseTest +@DisplayName("Diary 서비스의 ") +class DiaryServiceTest { + + @Autowired + private DiaryService diaryService; + @Autowired + private DiaryRepository diaryRepository; + @Autowired + private UserRepository userRepository; + + @BeforeEach + void saveUser(){ + userRepository.save(UserFixture.TEST_USER); + } + + @Test + @DisplayName("일기가 생성을 확인한다.") + void createDiary(){ + //given + UserDetail userDetail = UserFixture.TEST_USERDETAIL; + DiaryCreateReq diaryCreateReq = DiaryFixture.TEST_DIARY_CREATE_REQ; + String diaryUrl = "url"; + Diary expect = diaryRepository.save(DiaryFixture.TEST_DIARY); + + //when + diaryService.createDiary(userDetail, diaryCreateReq, diaryUrl); + Diary actual = diaryService.findDiaryWithUser(expect.getId()); + + //then + assertAll( + () -> assertThat(actual.getContents()).isEqualTo(expect.getContents()), + () -> assertThat(actual.getContents()).isEqualTo(expect.getContents()), + () -> assertThat(actual.getDiaryDate()).isEqualTo(expect.getDiaryDate()), + () -> assertThat(actual.getEmoji()).isEqualTo(expect.getEmoji()), + () -> assertThat(actual.getDrawingUrl()).isEqualTo(expect.getDrawingUrl()), + () -> assertThat(actual.getWeather()).isEqualTo(expect.getWeather()) + ); + } +} From 3c93a9821dad7a67f7bb51923f2a931de9f4daa1 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 20 Sep 2023 21:47:51 +0900 Subject: [PATCH 09/31] =?UTF-8?q?feat:=20DiaryFixture=20DELETE=5FDIARY=20?= =?UTF-8?q?=EA=B0=9D=EC=B2=B4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiary/support/fixture/DiaryFixture.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java b/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java index a98cc0a..9573ffa 100644 --- a/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java +++ b/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java @@ -8,17 +8,27 @@ public class DiaryFixture { - public static final Diary TEST_DIARY = Diary.builder() + public static final Diary CREATE_DIARY = Diary.builder() .title("일기 제목") .weather(Weather.SUNNY) .emoji("\uD83D\uDCAA") .contents("일기 내용") .drawingUrl("url") .diaryDate(LocalDate.of(2023,9,19)) - .user(UserFixture.TEST_USER) + .user(UserFixture.DIARY_CREATE_USER) .build(); - public static final DiaryCreateReq TEST_DIARY_CREATE_REQ = DiaryCreateReq.builder() + public static final Diary DELETE_DIARY = Diary.builder() + .title("일기 제목") + .weather(Weather.SUNNY) + .emoji("\uD83D\uDCAA") + .contents("일기 내용") + .drawingUrl("url") + .diaryDate(LocalDate.of(2023,9,20)) + .user(UserFixture.DIARY_DELETE_USER) + .build(); + + public static final DiaryCreateReq DIARY_CREATE_REQ = DiaryCreateReq.builder() .title("일기 제목") .weather("SUNNY") .emoji("\uD83D\uDCAA") From f18531e38b10c05a473cc8a58e2bc222320610c2 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 20 Sep 2023 21:48:33 +0900 Subject: [PATCH 10/31] =?UTF-8?q?refactor:=20deleteDiary=20service=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/aiary/aiary/domain/diary/service/DiaryService.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/aiary/aiary/domain/diary/service/DiaryService.java b/src/main/java/com/aiary/aiary/domain/diary/service/DiaryService.java index 80a3f1c..72c879c 100644 --- a/src/main/java/com/aiary/aiary/domain/diary/service/DiaryService.java +++ b/src/main/java/com/aiary/aiary/domain/diary/service/DiaryService.java @@ -10,7 +10,6 @@ import com.aiary.aiary.domain.user.entity.User; import com.aiary.aiary.domain.user.entity.UserDetail; import com.aiary.aiary.domain.user.exception.UnAuthorizedAccessException; -import com.aiary.aiary.domain.user.service.UserService; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; @@ -27,7 +26,6 @@ public class DiaryService { private static final String FIRST_DAY = "-01"; - private final UserService userService; private final DiaryRepository diaryRepository; private final DiaryMapper diaryMapper; @@ -37,9 +35,9 @@ public void createDiary(UserDetail userDetail, DiaryCreateReq diaryCreateReq, St } @Transactional - public void deleteDiary(UserDetail userDetail, Long diaryId){ + public void deleteDiary(UserDetail userDetail, Long diaryId){ Diary deleteDiary = findDiaryWithUser(diaryId); - User user = userService.findUserById(userDetail.getUserId()); + User user = userDetail.getUser(); if (!Objects.equals(user.getId(), deleteDiary.getUser().getId())) throw new UnAuthorizedAccessException(); From 7a3e63c42c283cf4fbde36e1ba400e42351149ae Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 20 Sep 2023 21:48:57 +0900 Subject: [PATCH 11/31] =?UTF-8?q?feat:=20DIARY=5FCREATE=5FUSER=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiary/support/fixture/UserFixture.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java b/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java index cb69090..4a075c1 100644 --- a/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java +++ b/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java @@ -6,16 +6,25 @@ public class UserFixture { - public static final User TEST_USER = User.builder() - .email("test@gmail.com") + public static final User DIARY_CREATE_USER = User.builder() + .email("Create@gmail.com") .password("Test012@") .nickname("테스트유저") .role(Role.USER) .build(); - public static final UserDetail TEST_USERDETAIL = UserDetail.builder() - .user(TEST_USER) + public static final UserDetail DIARY_CREATE_USERDETAIL = UserDetail.builder() + .user(DIARY_CREATE_USER) .build(); + public static final User DIARY_DELETE_USER = User.builder() + .email("Delete@gmail.com") + .password("Test012@") + .nickname("테스트유저") + .role(Role.USER) + .build(); + public static final UserDetail DIAEY_DELETE_USERDETAIL = UserDetail.builder() + .user(DIARY_DELETE_USER) + .build(); } From 4cd16bcca9e12df0d6bc9948c74f9239b720e1f9 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 20 Sep 2023 21:49:55 +0900 Subject: [PATCH 12/31] =?UTF-8?q?test:=20=EC=9D=BC=EA=B8=B0=EA=B0=80=20PK?= =?UTF-8?q?=EB=A1=9C=20=EC=82=AD=EC=A0=9C=EA=B0=80=20=EB=90=98=EB=8A=94?= =?UTF-8?q?=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diary/service/DiaryServiceTest.java | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java index 4e4a3b1..d9250d3 100644 --- a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java +++ b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java @@ -2,17 +2,18 @@ import com.aiary.aiary.domain.diary.dto.request.DiaryCreateReq; import com.aiary.aiary.domain.diary.entity.Diary; +import com.aiary.aiary.domain.diary.exception.DiaryNotFoundException; import com.aiary.aiary.domain.diary.repository.DiaryRepository; import com.aiary.aiary.domain.user.entity.UserDetail; import com.aiary.aiary.domain.user.repository.UserRepository; import com.aiary.aiary.support.database.DatabaseTest; import com.aiary.aiary.support.fixture.DiaryFixture; import com.aiary.aiary.support.fixture.UserFixture; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; + import static org.junit.jupiter.api.Assertions.assertAll; import static org.assertj.core.api.Assertions.*; @DatabaseTest @@ -26,19 +27,15 @@ class DiaryServiceTest { @Autowired private UserRepository userRepository; - @BeforeEach - void saveUser(){ - userRepository.save(UserFixture.TEST_USER); - } - @Test @DisplayName("일기가 생성을 확인한다.") void createDiary(){ //given - UserDetail userDetail = UserFixture.TEST_USERDETAIL; - DiaryCreateReq diaryCreateReq = DiaryFixture.TEST_DIARY_CREATE_REQ; + userRepository.save(UserFixture.DIARY_CREATE_USER); + UserDetail userDetail = UserFixture.DIARY_CREATE_USERDETAIL; + DiaryCreateReq diaryCreateReq = DiaryFixture.DIARY_CREATE_REQ; String diaryUrl = "url"; - Diary expect = diaryRepository.save(DiaryFixture.TEST_DIARY); + Diary expect = diaryRepository.save(DiaryFixture.CREATE_DIARY); //when diaryService.createDiary(userDetail, diaryCreateReq, diaryUrl); @@ -54,4 +51,24 @@ void createDiary(){ () -> assertThat(actual.getWeather()).isEqualTo(expect.getWeather()) ); } + + @Test + @DisplayName("일기가 PK로 삭제가 되는지 확인한다.") + void deleteDiary(){ + //given + userRepository.save(UserFixture.DIARY_DELETE_USER); + Diary expect = diaryRepository.save(DiaryFixture.DELETE_DIARY); + + //when + diaryService.deleteDiary(UserFixture.DIAEY_DELETE_USERDETAIL, expect.getId()); + + //then + assertAll( + () -> assertThat(expect.isDeleted()).isTrue(), + () -> assertThatThrownBy(() -> diaryService.findDiaryWithUser(expect.getId())) + .isInstanceOf(DiaryNotFoundException.class) + ); + + + } } From e49799ffd48ceac0ef9c5e0efb736ecbc9bd9877 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 21 Sep 2023 20:29:22 +0900 Subject: [PATCH 13/31] =?UTF-8?q?feat:=20DiaryFixture=20InsertDiaries=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiary/support/fixture/DiaryFixture.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java b/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java index 9573ffa..2f654d6 100644 --- a/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java +++ b/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java @@ -5,6 +5,8 @@ import com.aiary.aiary.domain.diary.entity.Weather; import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; public class DiaryFixture { @@ -35,4 +37,32 @@ public class DiaryFixture { .contents("일기 내용") .diaryDate(LocalDate.of(2023,9,19)) .build(); + + public static List InsertDiaries() { + List diaries = new ArrayList<>(); + Diary diary1 = Diary.builder() + .title("일기 제목1") + .weather(Weather.SUNNY) + .emoji("\uD83D\uDCAA") + .contents("일기 내용1") + .drawingUrl("url1") + .diaryDate(LocalDate.of(2023,9,21)) + .user(UserFixture.DIARY_FIND_MONTH_USER) + .build(); + + Diary diary2 = Diary.builder() + .title("일기 제목2") + .weather(Weather.SUNNY) + .emoji("\uD83D\uDCAA") + .contents("일기 내용2") + .drawingUrl("url1") + .diaryDate(LocalDate.of(2023,9,22)) + .user(UserFixture.DIARY_FIND_MONTH_USER) + .build(); + + diaries.add(diary1); + diaries.add(diary2); + + return diaries; + } } From 478f921c58ce67846c580a54a00c1d0612a85af3 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 21 Sep 2023 20:29:41 +0900 Subject: [PATCH 14/31] =?UTF-8?q?feat:=20UserFixture=20DIARY=5FFIND=5FMONT?= =?UTF-8?q?H=5FUSER=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/aiary/aiary/support/fixture/UserFixture.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java b/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java index 4a075c1..962412e 100644 --- a/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java +++ b/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java @@ -27,4 +27,15 @@ public class UserFixture { public static final UserDetail DIAEY_DELETE_USERDETAIL = UserDetail.builder() .user(DIARY_DELETE_USER) .build(); + + public static final User DIARY_FIND_MONTH_USER = User.builder() + .email("Find@gmail.com") + .password("Test012@") + .nickname("테스트유저") + .role(Role.USER) + .build(); + + public static final UserDetail DIARY_FIND_MONTH_USERDETAIL = UserDetail.builder() + .user(DIARY_FIND_MONTH_USER) + .build(); } From 4f1dcb4c7f97e749bdae102b791a6cda02dadead Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 21 Sep 2023 20:29:57 +0900 Subject: [PATCH 15/31] =?UTF-8?q?test:=20=EC=9D=BC=EA=B8=B0=EB=93=A4?= =?UTF-8?q?=EC=9D=84=20=EB=8B=AC=20=EB=B3=84=EB=A1=9C=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diary/service/DiaryServiceTest.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java index d9250d3..cd00429 100644 --- a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java +++ b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java @@ -1,6 +1,8 @@ package com.aiary.aiary.domain.diary.service; import com.aiary.aiary.domain.diary.dto.request.DiaryCreateReq; +import com.aiary.aiary.domain.diary.dto.response.DiaryRes; +import com.aiary.aiary.domain.diary.dto.response.MonthlyDiaryRes; import com.aiary.aiary.domain.diary.entity.Diary; import com.aiary.aiary.domain.diary.exception.DiaryNotFoundException; import com.aiary.aiary.domain.diary.repository.DiaryRepository; @@ -14,6 +16,8 @@ import org.springframework.beans.factory.annotation.Autowired; +import java.util.List; + import static org.junit.jupiter.api.Assertions.assertAll; import static org.assertj.core.api.Assertions.*; @DatabaseTest @@ -68,7 +72,23 @@ void deleteDiary(){ () -> assertThatThrownBy(() -> diaryService.findDiaryWithUser(expect.getId())) .isInstanceOf(DiaryNotFoundException.class) ); + } + + @Test + @DisplayName("일기들을 달 별로 조회할 수 있다.") + void findMonthlyDiaryByDate(){ + //given + userRepository.save(UserFixture.DIARY_FIND_MONTH_USER); + diaryRepository.saveAll(DiaryFixture.InsertDiaries()); + //when + MonthlyDiaryRes monthlyDiaryRes = diaryService.findMonthlyDiaryByDate(UserFixture.DIARY_FIND_MONTH_USERDETAIL, "2023-09"); + List diaryRes = monthlyDiaryRes.getMonthlyDiaryRes(); + //then + assertThat(diaryRes.size()).isEqualTo(2); + assertThat(diaryRes.get(0).getTitle()).isEqualTo("일기 제목2"); + assertThat(diaryRes.get(1).getTitle()).isEqualTo("일기 제목1"); } + } From 6348acbe63650a76efac55b11fbb33c5751fc2ee Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 21 Sep 2023 20:59:42 +0900 Subject: [PATCH 16/31] =?UTF-8?q?refactor:=20request=20DTO=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/aiary/aiary/domain/diary/dto/mapper/DiaryMapper.java | 4 ++-- .../aiary/domain/diary/dto/response/SearchDiariesRes.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/aiary/aiary/domain/diary/dto/mapper/DiaryMapper.java b/src/main/java/com/aiary/aiary/domain/diary/dto/mapper/DiaryMapper.java index ddb48b6..a399523 100644 --- a/src/main/java/com/aiary/aiary/domain/diary/dto/mapper/DiaryMapper.java +++ b/src/main/java/com/aiary/aiary/domain/diary/dto/mapper/DiaryMapper.java @@ -49,12 +49,12 @@ public MonthlyDiaryRes toMonthlyDiaryList(List monthlyDiaries){ } public SearchDiariesRes toDiarySlice(Slice diaries){ - List diaryInfos = diaries.stream() + List diaryRes = diaries.stream() .map(this::toEntity) .collect(Collectors.toList()); return SearchDiariesRes.builder() - .diaryInfos(diaryInfos) + .diaryRes(diaryRes) .curPageNumber(diaries.getNumber()) .hasNext(diaries.hasNext()) .hasPrevious(diaries.hasPrevious()) diff --git a/src/main/java/com/aiary/aiary/domain/diary/dto/response/SearchDiariesRes.java b/src/main/java/com/aiary/aiary/domain/diary/dto/response/SearchDiariesRes.java index 41c1f2d..3685c50 100644 --- a/src/main/java/com/aiary/aiary/domain/diary/dto/response/SearchDiariesRes.java +++ b/src/main/java/com/aiary/aiary/domain/diary/dto/response/SearchDiariesRes.java @@ -12,7 +12,7 @@ @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) public class SearchDiariesRes { - private List diaryInfos; + private List diaryRes; private int curPageNumber; private boolean hasNext; private boolean hasPrevious; From f6a8a397cf00ff26a100c1056f38858eb765382e Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 21 Sep 2023 21:00:05 +0900 Subject: [PATCH 17/31] =?UTF-8?q?refactor:=20pageRequest=20size=20?= =?UTF-8?q?=EA=B8=B0=EB=B3=B8=20=EA=B0=92=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiary/aiary/domain/diary/controller/DiaryController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/aiary/aiary/domain/diary/controller/DiaryController.java b/src/main/java/com/aiary/aiary/domain/diary/controller/DiaryController.java index 1935b71..c26cdbd 100644 --- a/src/main/java/com/aiary/aiary/domain/diary/controller/DiaryController.java +++ b/src/main/java/com/aiary/aiary/domain/diary/controller/DiaryController.java @@ -61,7 +61,7 @@ public ResponseEntity getMonthlyDiary(@AuthenticationPrincipal U @GetMapping("/search") public ResponseEntity searchDiariesByKeyWord(@AuthenticationPrincipal UserDetail user, @RequestParam(defaultValue = "0", required = false) int page, - @RequestParam(defaultValue = "10", required = false)int size, + @RequestParam(defaultValue = "40", required = false)int size, @RequestParam("diary_date") String diaryDate, @RequestParam String keyword){ PageRequest pageRequest = PageRequest.of(page, size); From 162778af92b11feff7c33e21c1e3e4f7fcc152e9 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 21 Sep 2023 21:00:45 +0900 Subject: [PATCH 18/31] =?UTF-8?q?feat:=20DiaryFixture=20INSERT=5FSEARCH=5F?= =?UTF-8?q?DIARIES=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiary/support/fixture/DiaryFixture.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java b/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java index 2f654d6..3ac2d84 100644 --- a/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java +++ b/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java @@ -38,7 +38,7 @@ public class DiaryFixture { .diaryDate(LocalDate.of(2023,9,19)) .build(); - public static List InsertDiaries() { + public static List INSERT_FIND_DIARIES() { List diaries = new ArrayList<>(); Diary diary1 = Diary.builder() .title("일기 제목1") @@ -65,4 +65,32 @@ public static List InsertDiaries() { return diaries; } + + public static List INSERT_SEARCH_DIARIES() { + List diaries = new ArrayList<>(); + Diary diary1 = Diary.builder() + .title("일기 제목1") + .weather(Weather.SUNNY) + .emoji("\uD83D\uDCAA") + .contents("일기 내용1") + .drawingUrl("url1") + .diaryDate(LocalDate.of(2023,9,21)) + .user(UserFixture.DIARY_SEARCH_USER) + .build(); + + Diary diary2 = Diary.builder() + .title("일기 제목2") + .weather(Weather.SUNNY) + .emoji("\uD83D\uDCAA") + .contents("일기 내용2") + .drawingUrl("url1") + .diaryDate(LocalDate.of(2023,9,22)) + .user(UserFixture.DIARY_SEARCH_USER) + .build(); + + diaries.add(diary1); + diaries.add(diary2); + + return diaries; + } } From 1f7707756b86623d87959e1b51a9caea95650b25 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 21 Sep 2023 21:01:09 +0900 Subject: [PATCH 19/31] =?UTF-8?q?feat:=20UserFixture=20DIARY=5FSEARCH=5FUS?= =?UTF-8?q?ER=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/aiary/aiary/support/fixture/UserFixture.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java b/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java index 962412e..d07661b 100644 --- a/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java +++ b/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java @@ -38,4 +38,15 @@ public class UserFixture { public static final UserDetail DIARY_FIND_MONTH_USERDETAIL = UserDetail.builder() .user(DIARY_FIND_MONTH_USER) .build(); + + public static final User DIARY_SEARCH_USER = User.builder() + .email("Search@gmail.com") + .password("Test012@") + .nickname("테스트유저") + .role(Role.USER) + .build(); + + public static final UserDetail DIARY_SEARCH_USERDETAIL = UserDetail.builder() + .user(DIARY_SEARCH_USER) + .build(); } From 14dcaf0b540b920b3f33552dc37714a1c0617a37 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 21 Sep 2023 21:01:41 +0900 Subject: [PATCH 20/31] =?UTF-8?q?test:=20=ED=82=A4=EC=9B=8C=EB=93=9C?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=9C=EB=AA=A9,=EB=82=B4=EC=9A=A9=EC=9D=84=20?= =?UTF-8?q?=ED=8F=AC=ED=95=A8=ED=95=9C=20=EC=9D=BC=EA=B8=B0=EB=93=A4?= =?UTF-8?q?=EC=9D=84=20=EA=B2=80=EC=83=89=ED=95=A0=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diary/service/DiaryServiceTest.java | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java index cd00429..5495eff 100644 --- a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java +++ b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java @@ -3,6 +3,7 @@ import com.aiary.aiary.domain.diary.dto.request.DiaryCreateReq; import com.aiary.aiary.domain.diary.dto.response.DiaryRes; import com.aiary.aiary.domain.diary.dto.response.MonthlyDiaryRes; +import com.aiary.aiary.domain.diary.dto.response.SearchDiariesRes; import com.aiary.aiary.domain.diary.entity.Diary; import com.aiary.aiary.domain.diary.exception.DiaryNotFoundException; import com.aiary.aiary.domain.diary.repository.DiaryRepository; @@ -11,9 +12,9 @@ import com.aiary.aiary.support.database.DatabaseTest; import com.aiary.aiary.support.fixture.DiaryFixture; import com.aiary.aiary.support.fixture.UserFixture; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; import java.util.List; @@ -79,7 +80,7 @@ void deleteDiary(){ void findMonthlyDiaryByDate(){ //given userRepository.save(UserFixture.DIARY_FIND_MONTH_USER); - diaryRepository.saveAll(DiaryFixture.InsertDiaries()); + diaryRepository.saveAll(DiaryFixture.INSERT_FIND_DIARIES()); //when MonthlyDiaryRes monthlyDiaryRes = diaryService.findMonthlyDiaryByDate(UserFixture.DIARY_FIND_MONTH_USERDETAIL, "2023-09"); @@ -91,4 +92,23 @@ void findMonthlyDiaryByDate(){ assertThat(diaryRes.get(1).getTitle()).isEqualTo("일기 제목1"); } + @Test + @DisplayName("키워드로 제목,내용을 포함한 일기들을 검색할 수 있다.") + void searchDiariesByDate(){ + //given + userRepository.save(UserFixture.DIARY_SEARCH_USER); + diaryRepository.saveAll(DiaryFixture.INSERT_SEARCH_DIARIES()); + PageRequest pageRequest = PageRequest.of(0, 40); + + //when + SearchDiariesRes searchDiariesRes = diaryService.searchDiariesByKeyword(UserFixture.DIARY_SEARCH_USERDETAIL + , pageRequest, "2023-09", "내용"); + List diaryRes = searchDiariesRes.getDiaryRes(); + + //then + assertThat(diaryRes.size()).isEqualTo(2); + assertThat(diaryRes.get(0).getContents()).isEqualTo("일기 내용2"); + assertThat(diaryRes.get(1).getContents()).isEqualTo("일기 내용1"); + } + } From 816e17f3854bac3029dbb51b9712d4c1a179a46f Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 21 Sep 2023 23:20:52 +0900 Subject: [PATCH 21/31] =?UTF-8?q?test:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EA=B0=80=20=EC=9E=91=EC=84=B1=ED=95=9C=20=EC=9D=BC=EA=B8=B0?= =?UTF-8?q?=EA=B0=80=20=EC=82=AD=EC=A0=9C=EB=90=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/diary/service/DiaryServiceTest.java | 18 ++++++++++++------ .../aiary/support/fixture/DiaryFixture.java | 10 ++++++++++ .../aiary/support/fixture/UserFixture.java | 11 +++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java index 5495eff..a1c07ec 100644 --- a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java +++ b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java @@ -8,6 +8,7 @@ import com.aiary.aiary.domain.diary.exception.DiaryNotFoundException; import com.aiary.aiary.domain.diary.repository.DiaryRepository; import com.aiary.aiary.domain.user.entity.UserDetail; +import com.aiary.aiary.domain.user.exception.UnAuthorizedAccessException; import com.aiary.aiary.domain.user.repository.UserRepository; import com.aiary.aiary.support.database.DatabaseTest; import com.aiary.aiary.support.fixture.DiaryFixture; @@ -58,20 +59,25 @@ void createDiary(){ } @Test - @DisplayName("일기가 PK로 삭제가 되는지 확인한다.") + @DisplayName("사용자가 작성한 일기가 PK로 삭제가 되는지 확인한다.") void deleteDiary(){ //given userRepository.save(UserFixture.DIARY_DELETE_USER); - Diary expect = diaryRepository.save(DiaryFixture.DELETE_DIARY); + userRepository.save(UserFixture.DIARY_DELETE_UNAUTHOR_USER); + Diary diary = diaryRepository.save(DiaryFixture.DELETE_DIARY); + Diary unAuthorDiary = diaryRepository.save(DiaryFixture.DELETE_UNAUTHOR_DIARY); //when - diaryService.deleteDiary(UserFixture.DIAEY_DELETE_USERDETAIL, expect.getId()); + diaryService.deleteDiary(UserFixture.DIAEY_DELETE_USERDETAIL, diary.getId()); //then assertAll( - () -> assertThat(expect.isDeleted()).isTrue(), - () -> assertThatThrownBy(() -> diaryService.findDiaryWithUser(expect.getId())) - .isInstanceOf(DiaryNotFoundException.class) + () -> assertThat(diary.isDeleted()).isTrue(), + () -> assertThatThrownBy(() -> diaryService.findDiaryWithUser(diary.getId())) + .isInstanceOf(DiaryNotFoundException.class), + () -> assertThatThrownBy(() -> diaryService.deleteDiary(UserFixture.DIAEY_DELETE_UNAUTHOR_USERDETAIL, unAuthorDiary.getId())) + .isInstanceOf(UnAuthorizedAccessException.class) + .hasMessageContaining("권한이 없는 사용자") ); } diff --git a/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java b/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java index 3ac2d84..19192cb 100644 --- a/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java +++ b/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java @@ -30,6 +30,16 @@ public class DiaryFixture { .user(UserFixture.DIARY_DELETE_USER) .build(); + public static final Diary DELETE_UNAUTHOR_DIARY = Diary.builder() + .title("일기 제목") + .weather(Weather.SUNNY) + .emoji("\uD83D\uDCAA") + .contents("일기 내용") + .drawingUrl("url") + .diaryDate(LocalDate.of(2023,9,20)) + .user(UserFixture.DIARY_DELETE_USER) + .build(); + public static final DiaryCreateReq DIARY_CREATE_REQ = DiaryCreateReq.builder() .title("일기 제목") .weather("SUNNY") diff --git a/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java b/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java index d07661b..16102d4 100644 --- a/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java +++ b/src/test/java/com/aiary/aiary/support/fixture/UserFixture.java @@ -28,6 +28,17 @@ public class UserFixture { .user(DIARY_DELETE_USER) .build(); + public static final User DIARY_DELETE_UNAUTHOR_USER = User.builder() + .email("Unauthor@gmail.com") + .password("Test012@") + .nickname("테스트유저") + .role(Role.USER) + .build(); + + public static final UserDetail DIAEY_DELETE_UNAUTHOR_USERDETAIL = UserDetail.builder() + .user(DIARY_DELETE_UNAUTHOR_USER) + .build(); + public static final User DIARY_FIND_MONTH_USER = User.builder() .email("Find@gmail.com") .password("Test012@") From 97aa2311df67919fdcb082d99f9b83f9fafa902a Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Fri, 22 Sep 2023 00:00:06 +0900 Subject: [PATCH 22/31] =?UTF-8?q?chore:=20jacoco=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/build.gradle b/build.gradle index 9f9993d..eef8b9e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ plugins { id 'java' + id 'jacoco' id 'org.springframework.boot' version '2.7.14-SNAPSHOT' id 'io.spring.dependency-management' version '1.0.15.RELEASE' id "org.asciidoctor.jvm.convert" version "3.3.2" @@ -12,6 +13,48 @@ java { sourceCompatibility = '11' } +jacoco { + toolVersion = '0.8.5' +} + +// 테스트 태스크에 Jacoco 통합 +test{ + finalizedBy 'jacocoTestReport' +} + +// 테스트 작업이 완료된 후 'jacocoTestReport' 작업을 실행하도록 설정 +jacocoTestReport { + reports { + xml.required = false + csv.required = false + html.required = true + } + finalizedBy jacocoTestCoverageVerification +} + +// Jacoco 코드 커버리지 검증 설정 +jacocoTestCoverageVerification { + violationRules { + rule { + enabled = true + element = 'CLASS' + + limit { + counter = 'METHOD' + value = 'COVEREDRATIO' + minimum = 0.00 + } + + limit { + counter = 'INSTRUCTION' // 조건, 반복문 + value = 'COVEREDRATIO' + minimum = 0.00 + } + excludes = ["*.dto.*", "*.global.*", "*.AiaryApplication*", "*.config.*", "*.exceptions.*"] + } + } +} + repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } @@ -49,6 +92,7 @@ tasks.named('test') { } // 변수 선언 +// snippetsDir 변수는 생성된 스니펫 파일을 저장할 디렉토리를 지정합니다. 스니펫 파일은 API 엔드포인트에서 생성된 예제 요청 및 응답 정보를 포함합니다. ext { snippetsDir = file('build/generated-snippets') } From 4a1c444993be660057a8bd4841f959866f46e981 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Fri, 22 Sep 2023 00:23:44 +0900 Subject: [PATCH 23/31] =?UTF-8?q?chore:=20jacoco=20=EB=94=94=EB=A0=89?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index eef8b9e..1cfe7ff 100644 --- a/build.gradle +++ b/build.gradle @@ -30,6 +30,17 @@ jacocoTestReport { html.required = true } finalizedBy jacocoTestCoverageVerification + afterEvaluate { + classDirectories.setFrom(files(classDirectories.files.collect { + fileTree(dir: it, exclude: [ + '**/dto/**', + "**/*Application*", + "**/global/**", + "**/config/**", + "**/exceptions/**" + ]) + })) + } } // Jacoco 코드 커버리지 검증 설정 @@ -50,7 +61,6 @@ jacocoTestCoverageVerification { value = 'COVEREDRATIO' minimum = 0.00 } - excludes = ["*.dto.*", "*.global.*", "*.AiaryApplication*", "*.config.*", "*.exceptions.*"] } } } From 50182fd830b63737afd7433028cab962bddd7240 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 28 Sep 2023 21:26:54 +0900 Subject: [PATCH 24/31] =?UTF-8?q?feat:=20CustomMockUser=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../support/utils/WithCustomMockUser.java | 13 +++++++ ...hCustomMockUserSecurityContextFactory.java | 35 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/test/java/com/aiary/aiary/support/utils/WithCustomMockUser.java create mode 100644 src/test/java/com/aiary/aiary/support/utils/WithCustomMockUserSecurityContextFactory.java diff --git a/src/test/java/com/aiary/aiary/support/utils/WithCustomMockUser.java b/src/test/java/com/aiary/aiary/support/utils/WithCustomMockUser.java new file mode 100644 index 0000000..a66d11f --- /dev/null +++ b/src/test/java/com/aiary/aiary/support/utils/WithCustomMockUser.java @@ -0,0 +1,13 @@ +package com.aiary.aiary.support.utils; + +import org.springframework.security.test.context.support.WithSecurityContext; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +@WithSecurityContext(factory = WithCustomMockUserSecurityContextFactory.class) +public @interface WithCustomMockUser { + String userUuid() default "test@email"; + String role() default "USER"; +} diff --git a/src/test/java/com/aiary/aiary/support/utils/WithCustomMockUserSecurityContextFactory.java b/src/test/java/com/aiary/aiary/support/utils/WithCustomMockUserSecurityContextFactory.java new file mode 100644 index 0000000..2c6884e --- /dev/null +++ b/src/test/java/com/aiary/aiary/support/utils/WithCustomMockUserSecurityContextFactory.java @@ -0,0 +1,35 @@ +package com.aiary.aiary.support.utils; + +import com.aiary.aiary.domain.user.entity.Role; +import com.aiary.aiary.domain.user.entity.User; +import com.aiary.aiary.domain.user.entity.UserDetail; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.test.context.support.WithSecurityContextFactory; + +import java.util.List; + +public class WithCustomMockUserSecurityContextFactory implements WithSecurityContextFactory { + + @Override + public SecurityContext createSecurityContext(WithCustomMockUser annotation) { + String userEmail = annotation.userUuid(); + String role = annotation.role(); + + User user = User.builder() + .email(userEmail) + .nickname("테스트 유저") + .password("Test012@") + .role(Role.valueOf(role)) + .build(); + UserDetail userDetail = UserDetail.builder().user(user).build(); + + UsernamePasswordAuthenticationToken token = + new UsernamePasswordAuthenticationToken(userDetail, "password", List.of(new SimpleGrantedAuthority(role))); + SecurityContext context = SecurityContextHolder.getContext(); + context.setAuthentication(token); + return context; + } +} From 039568116b67b6aed079bef78749969746d81f70 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 28 Sep 2023 21:29:04 +0900 Subject: [PATCH 25/31] =?UTF-8?q?style:=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/diary/service/DiaryServiceTest.java | 14 +++++++------- ...{DiaryFixture.java => DiaryServiceFixture.java} | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) rename src/test/java/com/aiary/aiary/support/fixture/{DiaryFixture.java => DiaryServiceFixture.java} (99%) diff --git a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java index a1c07ec..d2256ae 100644 --- a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java +++ b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java @@ -11,7 +11,7 @@ import com.aiary.aiary.domain.user.exception.UnAuthorizedAccessException; import com.aiary.aiary.domain.user.repository.UserRepository; import com.aiary.aiary.support.database.DatabaseTest; -import com.aiary.aiary.support.fixture.DiaryFixture; +import com.aiary.aiary.support.fixture.DiaryServiceFixture; import com.aiary.aiary.support.fixture.UserFixture; import org.junit.jupiter.api.*; import org.springframework.beans.factory.annotation.Autowired; @@ -39,9 +39,9 @@ void createDiary(){ //given userRepository.save(UserFixture.DIARY_CREATE_USER); UserDetail userDetail = UserFixture.DIARY_CREATE_USERDETAIL; - DiaryCreateReq diaryCreateReq = DiaryFixture.DIARY_CREATE_REQ; + DiaryCreateReq diaryCreateReq = DiaryServiceFixture.DIARY_CREATE_REQ; String diaryUrl = "url"; - Diary expect = diaryRepository.save(DiaryFixture.CREATE_DIARY); + Diary expect = diaryRepository.save(DiaryServiceFixture.CREATE_DIARY); //when diaryService.createDiary(userDetail, diaryCreateReq, diaryUrl); @@ -64,8 +64,8 @@ void deleteDiary(){ //given userRepository.save(UserFixture.DIARY_DELETE_USER); userRepository.save(UserFixture.DIARY_DELETE_UNAUTHOR_USER); - Diary diary = diaryRepository.save(DiaryFixture.DELETE_DIARY); - Diary unAuthorDiary = diaryRepository.save(DiaryFixture.DELETE_UNAUTHOR_DIARY); + Diary diary = diaryRepository.save(DiaryServiceFixture.DELETE_DIARY); + Diary unAuthorDiary = diaryRepository.save(DiaryServiceFixture.DELETE_UNAUTHOR_DIARY); //when diaryService.deleteDiary(UserFixture.DIAEY_DELETE_USERDETAIL, diary.getId()); @@ -86,7 +86,7 @@ void deleteDiary(){ void findMonthlyDiaryByDate(){ //given userRepository.save(UserFixture.DIARY_FIND_MONTH_USER); - diaryRepository.saveAll(DiaryFixture.INSERT_FIND_DIARIES()); + diaryRepository.saveAll(DiaryServiceFixture.INSERT_FIND_DIARIES()); //when MonthlyDiaryRes monthlyDiaryRes = diaryService.findMonthlyDiaryByDate(UserFixture.DIARY_FIND_MONTH_USERDETAIL, "2023-09"); @@ -103,7 +103,7 @@ void findMonthlyDiaryByDate(){ void searchDiariesByDate(){ //given userRepository.save(UserFixture.DIARY_SEARCH_USER); - diaryRepository.saveAll(DiaryFixture.INSERT_SEARCH_DIARIES()); + diaryRepository.saveAll(DiaryServiceFixture.INSERT_SEARCH_DIARIES()); PageRequest pageRequest = PageRequest.of(0, 40); //when diff --git a/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java b/src/test/java/com/aiary/aiary/support/fixture/DiaryServiceFixture.java similarity index 99% rename from src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java rename to src/test/java/com/aiary/aiary/support/fixture/DiaryServiceFixture.java index 19192cb..1e874d3 100644 --- a/src/test/java/com/aiary/aiary/support/fixture/DiaryFixture.java +++ b/src/test/java/com/aiary/aiary/support/fixture/DiaryServiceFixture.java @@ -8,7 +8,7 @@ import java.util.ArrayList; import java.util.List; -public class DiaryFixture { +public class DiaryServiceFixture { public static final Diary CREATE_DIARY = Diary.builder() .title("일기 제목") From 9f774620c71b0b800d9efa6f4144f9d811a9332d Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 28 Sep 2023 21:29:21 +0900 Subject: [PATCH 26/31] =?UTF-8?q?feat:=20MockApiTest=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiary/support/utils/MockApiTest.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/test/java/com/aiary/aiary/support/utils/MockApiTest.java diff --git a/src/test/java/com/aiary/aiary/support/utils/MockApiTest.java b/src/test/java/com/aiary/aiary/support/utils/MockApiTest.java new file mode 100644 index 0000000..720e427 --- /dev/null +++ b/src/test/java/com/aiary/aiary/support/utils/MockApiTest.java @@ -0,0 +1,48 @@ +package com.aiary.aiary.support.utils; + +import com.aiary.aiary.AiaryApplication; +import com.aiary.aiary.support.config.TestProfile; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.restdocs.RestDocumentationContextProvider; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.filter.CharacterEncodingFilter; + +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = AiaryApplication.class) +@ActiveProfiles(TestProfile.TEST) +@Disabled +public abstract class MockApiTest { + + protected MockMvc mockMvc; + protected ObjectMapper objectMapper = buildObjectMapper(); + + private ObjectMapper buildObjectMapper() { + final ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + return objectMapper; + } + + @BeforeEach + public void setupMockMvc( + WebApplicationContext ctx, + RestDocumentationContextProvider restDocumentationContextProvider) { + mockMvc = + MockMvcBuilders.webAppContextSetup(ctx) + .apply(documentationConfiguration(restDocumentationContextProvider)) + .addFilter(new CharacterEncodingFilter("UTF-8", true)) + .alwaysDo(print()) + .build(); + } +} From 037dc527a4ff787acaa33356c11eb4ae063da72c Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 28 Sep 2023 21:29:34 +0900 Subject: [PATCH 27/31] =?UTF-8?q?feat:=20DiaryControllerFixture=20CREATE?= =?UTF-8?q?=5FREQ=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../support/fixture/DiaryControllerFixture.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/test/java/com/aiary/aiary/support/fixture/DiaryControllerFixture.java diff --git a/src/test/java/com/aiary/aiary/support/fixture/DiaryControllerFixture.java b/src/test/java/com/aiary/aiary/support/fixture/DiaryControllerFixture.java new file mode 100644 index 0000000..9e9f940 --- /dev/null +++ b/src/test/java/com/aiary/aiary/support/fixture/DiaryControllerFixture.java @@ -0,0 +1,16 @@ +package com.aiary.aiary.support.fixture; + +import com.aiary.aiary.domain.diary.dto.request.DiaryCreateReq; + +import java.time.LocalDate; + +public class DiaryControllerFixture { + + public static final DiaryCreateReq CREATE_REQ = DiaryCreateReq.builder() + .title("일기 제목") + .contents("일기 내용") + .diaryDate(LocalDate.of(2023, 9, 24)) + .weather("SUNNY") + .emoji("\uD83D\uDCAA") + .build(); +} From aef9cba91da8dcfe813e852a2eb0ff12dcd66484 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 28 Sep 2023 21:29:56 +0900 Subject: [PATCH 28/31] =?UTF-8?q?test:=20=EC=9D=BC=EA=B8=B0=EA=B0=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=EB=90=98=EB=8A=94=EC=A7=80=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diary/controller/DiaryControllerTest.java | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/test/java/com/aiary/aiary/domain/diary/controller/DiaryControllerTest.java diff --git a/src/test/java/com/aiary/aiary/domain/diary/controller/DiaryControllerTest.java b/src/test/java/com/aiary/aiary/domain/diary/controller/DiaryControllerTest.java new file mode 100644 index 0000000..afcae7c --- /dev/null +++ b/src/test/java/com/aiary/aiary/domain/diary/controller/DiaryControllerTest.java @@ -0,0 +1,83 @@ +package com.aiary.aiary.domain.diary.controller; + +import com.aiary.aiary.domain.diary.dto.request.DiaryCreateReq; +import com.aiary.aiary.domain.diary.service.DiaryService; +import com.aiary.aiary.global.s3.service.S3UploadService; +import com.aiary.aiary.support.fixture.DiaryControllerFixture; +import com.aiary.aiary.support.utils.MockApiTest; +import com.aiary.aiary.support.utils.WithCustomMockUser; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpHeaders; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.test.web.servlet.ResultActions; + +import java.nio.charset.StandardCharsets; + +import static com.aiary.aiary.support.docs.ApiDocumentUtils.getDocumentRequest; +import static com.aiary.aiary.support.docs.ApiDocumentUtils.getDocumentResponse; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.multipart; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + + +@WebMvcTest(DiaryController.class) +@ExtendWith(RestDocumentationExtension.class) +@DisplayName("Diary 컨트롤러의 ") +class DiaryControllerTest extends MockApiTest { + + @MockBean + private DiaryService diaryService; + @MockBean + private S3UploadService s3UploadService; + + @Test + @WithCustomMockUser + @DisplayName("일기가 등록되는지 확인한다.") + void createDiary() throws Exception { + + MockMultipartFile file = new MockMultipartFile( + "file", // 파라미터 이름 + "file_name", // 파일 이름 + "image/jpeg",// 파일 타입 + "test file".getBytes(StandardCharsets.UTF_8) // 파일 내용 + ); + given(s3UploadService.saveFile(any(), any())).willReturn(String.valueOf(file)); + + DiaryCreateReq createReq = DiaryControllerFixture.CREATE_REQ; + String jsonByCreateReq = objectMapper.writeValueAsString(createReq); + MockMultipartFile request = new MockMultipartFile( + "createRequest", + "createRequest", + "application/json", + jsonByCreateReq.getBytes(StandardCharsets.UTF_8) + ); + String token = "accessToken"; + diaryService.createDiary(any(), any(), any()); + + ResultActions perform = + mockMvc.perform( + multipart("/diaries") + .file(file) + .file(request) + .header(HttpHeaders.AUTHORIZATION, "Bearer " + token) + ); + + // then + perform.andExpect(status().isOk()); + + // docs + perform.andDo(print()) + .andDo(document("register diary", + getDocumentRequest(), + getDocumentResponse())); + + } +} \ No newline at end of file From f9b648cedde8d7635151a67ff9ee4d67493bf014 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Thu, 28 Sep 2023 22:24:47 +0900 Subject: [PATCH 29/31] =?UTF-8?q?test:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EA=B0=80=20=EC=9E=91=EC=84=B1=ED=95=9C=20=EC=9D=BC=EA=B8=B0?= =?UTF-8?q?=EA=B0=80=20PK=EB=A1=9C=20=EC=82=AD=EC=A0=9C=EB=90=A0=20?= =?UTF-8?q?=EC=88=98=20=EC=9E=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diary/controller/DiaryControllerTest.java | 29 ++++++++- .../diary/service/DiaryServiceTest.java | 6 +- .../aiary/support/docs/RestDocumentTest.java | 61 ------------------- 3 files changed, 29 insertions(+), 67 deletions(-) delete mode 100644 src/test/java/com/aiary/aiary/support/docs/RestDocumentTest.java diff --git a/src/test/java/com/aiary/aiary/domain/diary/controller/DiaryControllerTest.java b/src/test/java/com/aiary/aiary/domain/diary/controller/DiaryControllerTest.java index afcae7c..e013976 100644 --- a/src/test/java/com/aiary/aiary/domain/diary/controller/DiaryControllerTest.java +++ b/src/test/java/com/aiary/aiary/domain/diary/controller/DiaryControllerTest.java @@ -22,7 +22,9 @@ import static com.aiary.aiary.support.docs.ApiDocumentUtils.getDocumentResponse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doNothing; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.multipart; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -30,7 +32,7 @@ @WebMvcTest(DiaryController.class) @ExtendWith(RestDocumentationExtension.class) -@DisplayName("Diary 컨트롤러의 ") +@DisplayName("Diary 컨트롤러에 ") class DiaryControllerTest extends MockApiTest { @MockBean @@ -40,9 +42,9 @@ class DiaryControllerTest extends MockApiTest { @Test @WithCustomMockUser - @DisplayName("일기가 등록되는지 확인한다.") + @DisplayName("일기가 등록될 수 있다.") void createDiary() throws Exception { - + //given MockMultipartFile file = new MockMultipartFile( "file", // 파라미터 이름 "file_name", // 파일 이름 @@ -62,6 +64,7 @@ void createDiary() throws Exception { String token = "accessToken"; diaryService.createDiary(any(), any(), any()); + //when ResultActions perform = mockMvc.perform( multipart("/diaries") @@ -80,4 +83,24 @@ void createDiary() throws Exception { getDocumentResponse())); } + + @Test + @DisplayName("사용자가 작성한 일기가 PK로 삭제될 수 있다.") + void deleteDiary() throws Exception { + //given + doNothing().when(diaryService).deleteDiary(any(), any()); + + //when + ResultActions perform = + mockMvc.perform( + delete("/diaries/{diaryId}", 1L)); + //then + perform.andExpect(status().isOk()); + + //docs + perform.andDo(print()) + .andDo(document("delete diary", + getDocumentRequest(), + getDocumentResponse())); + } } \ No newline at end of file diff --git a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java index d2256ae..936ea7f 100644 --- a/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java +++ b/src/test/java/com/aiary/aiary/domain/diary/service/DiaryServiceTest.java @@ -23,7 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.assertj.core.api.Assertions.*; @DatabaseTest -@DisplayName("Diary 서비스의 ") +@DisplayName("Diary 서비스에 ") class DiaryServiceTest { @Autowired @@ -34,7 +34,7 @@ class DiaryServiceTest { private UserRepository userRepository; @Test - @DisplayName("일기가 생성을 확인한다.") + @DisplayName("일기가 생성할 수 있다.") void createDiary(){ //given userRepository.save(UserFixture.DIARY_CREATE_USER); @@ -59,7 +59,7 @@ void createDiary(){ } @Test - @DisplayName("사용자가 작성한 일기가 PK로 삭제가 되는지 확인한다.") + @DisplayName("사용자가 작성한 일기가 PK로 삭제가 될 수 있다.") void deleteDiary(){ //given userRepository.save(UserFixture.DIARY_DELETE_USER); diff --git a/src/test/java/com/aiary/aiary/support/docs/RestDocumentTest.java b/src/test/java/com/aiary/aiary/support/docs/RestDocumentTest.java deleted file mode 100644 index c752b86..0000000 --- a/src/test/java/com/aiary/aiary/support/docs/RestDocumentTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.aiary.aiary.support.docs; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.extension.ExtendWith; -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.Import; -import org.springframework.data.jpa.mapping.JpaMetamodelMappingContext; -import org.springframework.restdocs.RestDocumentationContextProvider; -import org.springframework.restdocs.RestDocumentationExtension; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.filter.CharacterEncodingFilter; - -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; - -@ExtendWith({RestDocumentationExtension.class, SpringExtension.class}) -@Import(RestDocsConfiguration.class) -@AutoConfigureRestDocs -@WebMvcTest -public abstract class RestDocumentTest { - - @Autowired - private ObjectMapper objectMapper; - protected MockMvc mockMvc; - - /* - * MockMvc - * -> 웹 어플리케이션의 웹 계층을 테스트 하기 위해 실제 HTTP 서버를 구동하지 않아도 되므로 테스트 속도를 향상시키고 - * 의존성을 줄일 수 있다. (테스트 중 외부 리소스에 독립적으로 테스트 수행가능) - * */ - @MockBean - private JpaMetamodelMappingContext jpaMetamodelMappingContext; - - protected String toRequestBody(Object value) throws JsonProcessingException { - return objectMapper.writeValueAsString(value); - } - - /* - * 1. @BeforeEach - * -> 각 테스트 메서드가 실행되기전에 수행되는 초기화 메서드 - * */ - @BeforeEach - public void setupMockMvc( - WebApplicationContext ctx, - RestDocumentationContextProvider restDocumentationContextProvider) { - mockMvc = - MockMvcBuilders.webAppContextSetup(ctx) - .apply(documentationConfiguration(restDocumentationContextProvider)) - .addFilter(new CharacterEncodingFilter("UTF-8", true)) - .alwaysDo(print()) - .build(); - } -} From 3d51d6982405efb184a12d62db4b1b11a2166764 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Fri, 29 Sep 2023 00:10:17 +0900 Subject: [PATCH 30/31] =?UTF-8?q?test:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EA=B0=80=20=EC=9E=91=EC=84=B1=ED=95=9C=20=EC=9D=BC=EA=B8=B0?= =?UTF-8?q?=EB=A5=BC=20=EB=8B=AC=EB=B3=84=EB=A1=9C=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../diary/controller/DiaryControllerTest.java | 50 ++++++++++++++++++- .../fixture/DiaryControllerFixture.java | 19 +++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/aiary/aiary/domain/diary/controller/DiaryControllerTest.java b/src/test/java/com/aiary/aiary/domain/diary/controller/DiaryControllerTest.java index e013976..9bf48c6 100644 --- a/src/test/java/com/aiary/aiary/domain/diary/controller/DiaryControllerTest.java +++ b/src/test/java/com/aiary/aiary/domain/diary/controller/DiaryControllerTest.java @@ -1,7 +1,10 @@ package com.aiary.aiary.domain.diary.controller; import com.aiary.aiary.domain.diary.dto.request.DiaryCreateReq; +import com.aiary.aiary.domain.diary.dto.response.DiaryRes; +import com.aiary.aiary.domain.diary.dto.response.MonthlyDiaryRes; import com.aiary.aiary.domain.diary.service.DiaryService; +import com.aiary.aiary.domain.user.entity.UserDetail; import com.aiary.aiary.global.s3.service.S3UploadService; import com.aiary.aiary.support.fixture.DiaryControllerFixture; import com.aiary.aiary.support.utils.MockApiTest; @@ -12,20 +15,26 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; import org.springframework.mock.web.MockMultipartFile; import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.restdocs.payload.JsonFieldType; import org.springframework.test.web.servlet.ResultActions; import java.nio.charset.StandardCharsets; +import java.util.List; import static com.aiary.aiary.support.docs.ApiDocumentUtils.getDocumentRequest; import static com.aiary.aiary.support.docs.ApiDocumentUtils.getDocumentResponse; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.doNothing; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.multipart; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -88,7 +97,7 @@ void createDiary() throws Exception { @DisplayName("사용자가 작성한 일기가 PK로 삭제될 수 있다.") void deleteDiary() throws Exception { //given - doNothing().when(diaryService).deleteDiary(any(), any()); + doNothing().when(diaryService).deleteDiary(any(UserDetail.class), any(Long.class)); //when ResultActions perform = @@ -103,4 +112,43 @@ void deleteDiary() throws Exception { getDocumentRequest(), getDocumentResponse())); } + + @Test + @DisplayName("사용자가 작성한 일기를 달별로 조회할 수 있다.") + void getMonthlyDiary() throws Exception { + // given + String diaryDate = "2023-09"; + List expectedDiaries = DiaryControllerFixture.MONTHLY_DIARIES(); + MonthlyDiaryRes monthlyDiaryRes = MonthlyDiaryRes.builder() + .monthlyDiaryRes(expectedDiaries) + .build(); + given(diaryService.findMonthlyDiaryByDate(any(UserDetail.class), eq(diaryDate))).willReturn(monthlyDiaryRes); + + // when + ResultActions perform = mockMvc.perform( + get("/diaries") + .param("diary_date", diaryDate) + .contentType(MediaType.APPLICATION_JSON)); + + // then + perform.andExpect(status().isOk()) + .andDo(print()) + .andDo(document("get monthlyDiaries", + getDocumentRequest(), + getDocumentResponse(), + responseFields( + fieldWithPath("code").description("상태 코드"), + fieldWithPath("message").description("응답 메시지"), + fieldWithPath("data").description("응답 데이터").type(JsonFieldType.OBJECT).optional(), + fieldWithPath("data.monthly_diary_info").description("월별 일기 정보").type(JsonFieldType.ARRAY).optional(), + fieldWithPath("data.monthly_diary_info[].diary_id").type(JsonFieldType.NUMBER).description("일기 ID").optional(), + fieldWithPath("data.monthly_diary_info[].title").type(JsonFieldType.STRING).description("일기 제목").optional(), + fieldWithPath("data.monthly_diary_info[].weather").type(JsonFieldType.STRING).description("일기 날씨").optional(), + fieldWithPath("data.monthly_diary_info[].emoji").type(JsonFieldType.STRING).description("이모지").optional(), + fieldWithPath("data.monthly_diary_info[].contents").type(JsonFieldType.STRING).description("일기 내용").optional(), + fieldWithPath("data.monthly_diary_info[].diary_date").type(JsonFieldType.STRING).description("일기 날짜").optional(), + fieldWithPath("data.monthly_diary_info[].drawing_url").type(JsonFieldType.STRING).description("일기 그림 URL").optional()) + )); + } + } \ No newline at end of file diff --git a/src/test/java/com/aiary/aiary/support/fixture/DiaryControllerFixture.java b/src/test/java/com/aiary/aiary/support/fixture/DiaryControllerFixture.java index 9e9f940..bdf0f3c 100644 --- a/src/test/java/com/aiary/aiary/support/fixture/DiaryControllerFixture.java +++ b/src/test/java/com/aiary/aiary/support/fixture/DiaryControllerFixture.java @@ -1,8 +1,13 @@ package com.aiary.aiary.support.fixture; import com.aiary.aiary.domain.diary.dto.request.DiaryCreateReq; +import com.aiary.aiary.domain.diary.dto.response.DiaryRes; +import com.aiary.aiary.domain.diary.entity.Weather; import java.time.LocalDate; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class DiaryControllerFixture { @@ -13,4 +18,18 @@ public class DiaryControllerFixture { .weather("SUNNY") .emoji("\uD83D\uDCAA") .build(); + + public static List MONTHLY_DIARIES() { + return IntStream.range(0, 5) + .mapToObj(i -> DiaryRes.builder() + .diaryId((long) i) + .title("일기 제목" + i) + .weather(Weather.SUNNY) + .emoji("\uD83D\uDCAA") + .contents("일기 내용" + i) + .drawingUrl("url" + i) + .diaryDate("2023-09-0" + (i + 1)) + .build()) + .collect(Collectors.toList()); + } } From bad42f2cfcefae8979f4b0cfced536c8e6158e7d Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Fri, 29 Sep 2023 00:26:44 +0900 Subject: [PATCH 31/31] =?UTF-8?q?docs:=20https://docs.api.com=20=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/aiary/aiary/support/docs/ApiDocumentUtils.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/aiary/aiary/support/docs/ApiDocumentUtils.java b/src/test/java/com/aiary/aiary/support/docs/ApiDocumentUtils.java index 103de41..39ce8e5 100644 --- a/src/test/java/com/aiary/aiary/support/docs/ApiDocumentUtils.java +++ b/src/test/java/com/aiary/aiary/support/docs/ApiDocumentUtils.java @@ -8,8 +8,12 @@ public interface ApiDocumentUtils { // OperationRequestPreprocessor 는 API 문서화를 위해 요청에 대한 사전처리를 수행 // prettyPrint() 메서드는 요청/응답을 보기 좋게 만듬. + // 문서상 uri 를 기본값인 http://localhost:8080 에서 https://docs.api.com 으로 변경하기 위해 사용합니다. static OperationRequestPreprocessor getDocumentRequest() { - return preprocessRequest(prettyPrint()); + return preprocessRequest(modifyUris() + .scheme("https") + .host("docs.api.com") + .removePort(), prettyPrint()); } // OperationResponsePreprocessor 는 API 문서화를 위해 응답에 대한 사전처리를 수행