diff --git a/BE/build.gradle b/BE/build.gradle index be6bf605e..c702fb4c3 100644 --- a/BE/build.gradle +++ b/BE/build.gradle @@ -2,12 +2,50 @@ plugins { id 'org.springframework.boot' version '2.6.6' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' + id 'org.asciidoctor.jvm.convert' version "3.3.2" } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' +configurations { + asciidoctorExtentions +} + +ext { + snippetsDir = file('build/generated-snippets') +} + +test { + outputs.dir snippetsDir +} + +asciidoctor { + inputs.dir snippetsDir + dependsOn test +} + +bootJar { + dependsOn asciidoctor + copy { + from "${asciidoctor.outputDir}" + into 'src/main/resources/static/docs' + } +} + +// docs html 에 파일 복사 +task copyDocument(type: Copy) { + dependsOn asciidoctor + + from file("build/asciidoc/html5/") + into file("src/main/resources/static/docs") +} + +build { + dependsOn copyDocument +} + repositories { mavenCentral() } @@ -19,6 +57,10 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jdbc:2.6.4' implementation 'org.springframework.boot:spring-boot-starter-jdbc' + // lombok + implementation 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + // DB implementation 'org.springframework.boot:spring-boot-starter-jdbc' implementation 'mysql:mysql-connector-java:8.0.28' @@ -28,8 +70,13 @@ dependencies { implementation 'io.springfox:springfox-swagger2:2.9.2' implementation 'io.springfox:springfox-swagger-ui:2.9.2' + // Spring Rest Docs + asciidoctorExtentions 'org.springframework.restdocs:spring-restdocs-asciidoctor' + testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' + // test - testImplementation 'org.springframework.boot:spring-boot-starter-test:2.5.5' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'io.rest-assured:rest-assured' } tasks.named('test') { diff --git a/BE/src/docs/asciidoc/api-doc.adoc b/BE/src/docs/asciidoc/api-doc.adoc new file mode 100644 index 000000000..7c9de2688 --- /dev/null +++ b/BE/src/docs/asciidoc/api-doc.adoc @@ -0,0 +1,18 @@ += Spring REST Docs +:toc: left +:toclevels: 2 +:sectlinks: + +[[resources-post]] +== Post + +[[resources-post-create]] +=== Post 생성 + +==== HTTP request + +include::{snippets}/전체 기획전 데이터/http-request.adoc[] + +==== HTTP response + +include::{snippets}/전체 기획전 데이터/http-response.adoc[] diff --git a/BE/src/main/java/com/example/be/controller/ApiError.java b/BE/src/main/java/com/example/be/controller/ApiError.java index b77f4117a..a8f7a32c2 100644 --- a/BE/src/main/java/com/example/be/controller/ApiError.java +++ b/BE/src/main/java/com/example/be/controller/ApiError.java @@ -13,7 +13,7 @@ public class ApiError { this(throwable.getMessage(), status); } - ApiError(String message, HttpStatus status) { + public ApiError(String message, HttpStatus status) { this.message = message; this.status = status.value(); } diff --git a/BE/src/main/java/com/example/be/controller/dish/DishController.java b/BE/src/main/java/com/example/be/controller/dish/DishController.java index 277ed812b..f6f986e10 100644 --- a/BE/src/main/java/com/example/be/controller/dish/DishController.java +++ b/BE/src/main/java/com/example/be/controller/dish/DishController.java @@ -1,17 +1,16 @@ package com.example.be.controller.dish; +import static com.example.be.controller.ApiResult.OK; + import com.example.be.controller.ApiResult; import com.example.be.controller.dish.dto.PlanningDataRequest; import com.example.be.service.dish.DishService; +import java.util.List; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - -import static com.example.be.controller.ApiResult.OK; - @RestController @RequestMapping("/api/dishes") public class DishController { @@ -23,10 +22,16 @@ public DishController(DishService dishService) { } @GetMapping - public ApiResult> getPlanningData() { - return OK(dishService.getPlanningData()); + public List getPlanningData() { + return dishService.getPlanningData(); } + +// @GetMapping +// public ApiResult> getPlanningData() { +// return OK(dishService.getPlanningData()); +// } + @GetMapping("{id}") public ApiResult getDishDetail(@PathVariable("id") Long id) { return OK(new DishDetail(dishService.getDishDetail(id))); diff --git a/BE/src/main/java/com/example/be/service/dish/DishService.java b/BE/src/main/java/com/example/be/service/dish/DishService.java index 0a5ea7cc8..c03fe9772 100644 --- a/BE/src/main/java/com/example/be/service/dish/DishService.java +++ b/BE/src/main/java/com/example/be/service/dish/DishService.java @@ -1,17 +1,13 @@ package com.example.be.service.dish; -import com.example.be.controller.ApiResult; -import com.example.be.controller.dish.DishDetail; import com.example.be.controller.dish.dto.PlanningDataRequest; -import com.example.be.controller.exception.UserTypeException; import com.example.be.domain.dish.Dish; import com.example.be.repository.dish.DishReadRepository; import com.example.be.repository.dish.DishRepository; +import java.util.List; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; - @Service public class DishService { diff --git a/BE/src/test/java/com/example/be/controller/dish/DishControllerTest.java b/BE/src/test/java/com/example/be/controller/dish/DishControllerTest.java new file mode 100644 index 000000000..e144d1e76 --- /dev/null +++ b/BE/src/test/java/com/example/be/controller/dish/DishControllerTest.java @@ -0,0 +1,98 @@ +package com.example.be.controller.dish; + +import static org.mockito.BDDMockito.given; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.example.be.controller.dish.dto.PlanningDataRequest; +import com.example.be.domain.dish.Badge; +import com.example.be.domain.dish.DeliveryType; +import com.example.be.domain.dish.DishStatus; +import com.example.be.service.dish.DishService; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +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.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.restdocs.RestDocumentationExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +@AutoConfigureMockMvc +@AutoConfigureRestDocs + +@ExtendWith(RestDocumentationExtension.class) +@WebMvcTest(DishController.class) +@DisplayName("API /api/dishes/* 컨트롤러 계층 단위 테스트") +class DishControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private DishService dishService; + +// @BeforeEach +// public void setUp(WebApplicationContext webApplicationContext, +// RestDocumentationContextProvider restDocumentation) { +// this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) +// .apply(documentationConfiguration(restDocumentation)) +// .build(); +// } + + @Test + void getPlanningDataTest() throws Exception { + List dishes = createTestData(); + + given(dishService.getPlanningData()) + .willReturn(dishes); + + ResultActions result = mockMvc.perform(MockMvcRequestBuilders.get("/api/dishes")); + + result + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andDo(document("sidedish", + responseFields( + fieldWithPath("[].title").description("title 제목 작성"), + fieldWithPath("[].description").description("description 본문 작성").optional(), + fieldWithPath("[].dishId").description("1"), + fieldWithPath("[].name").description("이름"), + fieldWithPath("[].normalPrice").description("10000"), + fieldWithPath("[].salePrice").description("9000"), + fieldWithPath("[].badge").description("NONE"), + fieldWithPath("[].deliveryType").description("NONE"), + fieldWithPath("[].thumbnail").description("naver.com"), + fieldWithPath("[].dishStatus").description("OUT_OF_STOCK"), + fieldWithPath("[].categoryId").description("1") + ) + )); + + } + + private List createTestData() { + List dishes = new ArrayList<>(); + dishes.add(0, + new PlanningDataRequest(1L, "이름", "설명", new BigDecimal(10000), new BigDecimal(9000), + Badge.NONE, DeliveryType.NONE, "naver.com", DishStatus.OUT_OT_STOCK, 1L, + "타이틀")); + dishes.add(1, + new PlanningDataRequest(2L, "이름2", "설명2", new BigDecimal(100002), new BigDecimal(90002), + Badge.NONE, DeliveryType.NONE, "naver.com222", DishStatus.OUT_OT_STOCK, 2L, + "타이틀2")); + + + return dishes; + } +} diff --git a/BE/src/test/resources/application.yml b/BE/src/test/resources/application.yml new file mode 100644 index 000000000..84b345a23 --- /dev/null +++ b/BE/src/test/resources/application.yml @@ -0,0 +1,21 @@ +spring: + datasource: + driverClassName: org.h2.Driver + url: jdbc:h2:mem:testdb + username: sa + sql: + init: + mode: always + schema-locations: classpath:testDB/schema.sql +# data-locations: classpath:testDB/data.sql + h2: + console: + enabled: true + path: /h2-console + mvc: + pathmatch: + matching-strategy: ant_path_matcher + +logging: + level: + web: DEBUG diff --git a/BE/src/test/resources/testDB/schema.sql b/BE/src/test/resources/testDB/schema.sql new file mode 100644 index 000000000..f6838566e --- /dev/null +++ b/BE/src/test/resources/testDB/schema.sql @@ -0,0 +1,30 @@ +DROP TABLE IF EXISTS dish; +CREATE TABLE dish +( + dish_id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(255) NULL, + description VARCHAR(255) NULL, + normal_price DECIMAL NULL, + sale_price DECIMAL NULL, + badge VARCHAR(255) NULL, + delivery_type VARCHAR(255) NULL, + thumbnail VARCHAR(255) NULL, + category_id BIGINT NOT NULL, + dish_status VARCHAR(255) NULL +); + + +DROP TABLE IF EXISTS category; +CREATE TABLE category +( + category_id BIGINT NOT NULL PRIMARY KEY, + title VARCHAR(255) +); + +DROP TABLE IF EXISTS users; +CREATE TABLE users +( + user_id BIGINT NOT NULL PRIMARY KEY, + login_id BIGINT NOT NULL, + password VARCHAR(60) NOT NULL +);